home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / diag / memsz153.zip / MEMSIZE.C < prev    next >
C/C++ Source or Header  |  1992-12-28  |  103KB  |  3,241 lines

  1. /****************************************************************** MEMSIZE.C
  2.  *                                        *
  3.  * System Resources Monitor                            *
  4.  *                                        *
  5.  * Revision 1.53 (12/28/92)                            *
  6.  *                                        *
  7.  * (C) Copyright 1991-1992 by Richard W. Papo.                    *
  8.  *                                        *
  9.  * This is 'FreeWare'.    As such, it may be copied and distributed        *
  10.  * freely.  If you want to use part of it in your own program, please        *
  11.  * give credit where credit is due.  If you want to change the            *
  12.  * program, please refer the change request to me or send me the        *
  13.  * modified source code.  I can be reached at CompuServe 72607,3111.        *
  14.  *                                        *
  15.  ****************************************************************************/
  16.  
  17. #define INCL_DEV
  18. #define INCL_DOS
  19. #define INCL_ERRORS
  20. #define INCL_WIN
  21. #define INCL_GPI
  22. #include <os2.h>
  23.  
  24. #include <direct.h>
  25. #include <process.h>
  26. #include <stdarg.h>
  27. #include <stddef.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <time.h>
  32.  
  33. #include <sys\types.h>
  34. #include <sys\stat.h>
  35.  
  36. #include "debug.h"
  37. #include "support.h"
  38. #include "about.h"
  39. #include "settimer.h"
  40.  
  41. #include "memsize.h"
  42.  
  43.  
  44. /****************************************************************************
  45.  *                                        *
  46.  *             Definitions & Declarations                *
  47.  *                                        *
  48.  ****************************************************************************/
  49.  
  50.   // Constants
  51.  
  52. #define PROGRAM_NAME        "MEMSIZE"
  53. #define CLASS_NAME        "MEMSIZE"
  54.  
  55. enum
  56. {
  57.   ITEM_CLOCK,
  58.   ITEM_MEMORYFREE,
  59.   ITEM_SWAPFILESIZE,
  60.   ITEM_SWAPDISKFREE,
  61.   ITEM_SPOOLFILESIZE,
  62.   ITEM_CPULOAD
  63. } ;
  64.  
  65. #define WM_REFRESH        WM_USER
  66.  
  67.  
  68.   // Data Types
  69.  
  70. typedef struct          // Data structure for item to be monitored.
  71. {
  72.   CHAR     Name [80] ;           // Text for item's profile name.
  73.   BOOL     Flag ;            // Flag: Show this item at this time?
  74.   CHAR     Label [80] ;           // Text to display on left part of line.
  75.   ULONG  Value ;           // Value to display on right part of line.
  76.   CHAR     MenuOption [80] ;     // Text to display in system menu.
  77.   USHORT MenuId ;           // ID for use in system menu.
  78.   ULONG  (*NewValue)           // Function to determine new value.
  79.     (PVOID,USHORT) ;
  80.   USHORT Parm ;            // Parameter to pass to NewValue function.
  81.   USHORT Divisor ;           // Amount to divide value by before display.
  82.   CHAR     Suffix ;           // Character to place after value.
  83. }
  84. ITEM, *PITEM ;
  85.  
  86. typedef struct          // Parameters saved to system.
  87. {
  88.   PITEM  Items ;        // Items to display.
  89.   int     ItemCount ;
  90.  
  91.   SWP     Position ;        // Window size & location.
  92.   BOOL     fPosition ;
  93.  
  94.   BOOL     HideControls ;     // User options.
  95.   USHORT TimerInterval ;
  96.  
  97.   CHAR     FontNameSize [80] ;    // Presentation Parameters
  98.   BOOL     fFontNameSize ;
  99.  
  100.   COLOR  BackColor ;
  101.   BOOL     fBackColor ;
  102.  
  103.   COLOR  TextColor ;
  104.   BOOL     fTextColor ;
  105. }
  106. PROFILE ;
  107.  
  108. typedef struct        // Data structure for window.
  109. {
  110.   HAB         hAB ;
  111.   HMODULE     Library ;
  112.  
  113.   ULONG      IdleCounter ;
  114.   ULONG      IdleCount ;
  115.   TID         IdleLoopTID ;
  116.   TID         MonitorLoopTID ;
  117.  
  118.   PROFILE     Profile ;
  119.  
  120.   HWND           hwndTitleBar ;
  121.   HWND           hwndSysMenu ;
  122.   HWND           hwndMinMax ;
  123.  
  124.   char           SwapPath [_MAX_PATH] ;
  125.   int         MinFree ;
  126.  
  127.   PCHAR      SpoolPath ;
  128.  
  129.   long         Width ;
  130.   long         Height ;
  131.  
  132.   COUNTRYINFO     CountryInfo ;
  133. }
  134. DATA, *PDATA ;
  135.  
  136. typedef struct
  137. {
  138.   HAB hAB ;
  139.   HMODULE Library ;
  140. }
  141. PARMS, *PPARMS ;
  142.  
  143. typedef struct
  144. {
  145.   PULONG Counter ;
  146. }
  147. IDLE_PARMS, *PIDLE_PARMS ;
  148.  
  149. typedef struct
  150. {
  151.   PULONG  Counter ;
  152.   PUSHORT Interval ;
  153.   HWND      Owner ;
  154. }
  155. MONITOR_PARMS, *PMONITOR_PARMS ;
  156.  
  157.  
  158.   // Function Prototypes
  159.  
  160. extern void main ( int argc, PCHAR argv[] ) ;
  161.  
  162. static MRESULT EXPENTRY MessageProcessor
  163. (
  164.   HWND hwnd,
  165.   USHORT msg,
  166.   MPARAM mp1,
  167.   MPARAM mp2
  168. ) ;
  169.  
  170. static METHODFUNCTION Create ;
  171. static METHODFUNCTION Destroy ;
  172. static METHODFUNCTION Size ;
  173. static METHODFUNCTION SaveApplication ;
  174. static METHODFUNCTION Paint ;
  175. static METHODFUNCTION Command ;
  176. static METHODFUNCTION ResetDefaults ;
  177. static METHODFUNCTION HideControlsCmd ;
  178. static METHODFUNCTION SetTimer ;
  179. static METHODFUNCTION About ;
  180. static METHODFUNCTION ButtonDown ;
  181. static METHODFUNCTION ButtonDblClick ;
  182. static METHODFUNCTION PresParamChanged ;
  183. static METHODFUNCTION SysColorChange ;
  184. static METHODFUNCTION QueryKeysHelp ;
  185. static METHODFUNCTION HelpError ;
  186. static METHODFUNCTION ExtHelpUndefined ;
  187. static METHODFUNCTION HelpSubitemNotFound ;
  188. static METHODFUNCTION Refresh ;
  189.  
  190. static void GetProfile ( HAB hAB, HMODULE Library, PROFILE *Profile ) ;
  191. static void PutProfile ( PROFILE *Profile ) ;
  192.  
  193. static PCHAR ScanSystemConfig ( PCHAR Keyword ) ;
  194.  
  195. static void ResizeWindow ( HWND hwnd, PROFILE *Profile ) ;
  196.  
  197. static void HideControls
  198. (
  199.   BOOL fHide,
  200.   HWND hwndFrame,
  201.   HWND hwndSysMenu,
  202.   HWND hwndTitleBar,
  203.   HWND hwndMinMax
  204. ) ;
  205.  
  206. static void UpdateWindow ( HWND hwnd, PDATA Data, BOOL All ) ;
  207.  
  208. static ULONG ComputeTime       ( PDATA Data, USHORT Dummy ) ;
  209. static ULONG ComputeFreeMemory ( PDATA Data, USHORT Dummy ) ;
  210. static ULONG ComputeSwapSize   ( PDATA Data, USHORT Dummy ) ;
  211. static ULONG ComputeSwapFree   ( PDATA Data, USHORT Dummy ) ;
  212. static ULONG ComputeSpoolSize  ( PDATA Data, USHORT Dummy ) ;
  213. static ULONG ComputeCpuLoad    ( PDATA Data, USHORT Dummy ) ;
  214. static ULONG ComputeDriveFree  ( PDATA Data, USHORT Drive ) ;
  215.  
  216. static void _far _cdecl IdleLoopThread ( PIDLE_PARMS Parms ) ;
  217. static void _far _cdecl MonitorLoopThread ( PMONITOR_PARMS Parms ) ;
  218.  
  219.  
  220. /****************************************************************************
  221.  *                                        *
  222.  *    Program Mainline                            *
  223.  *                                        *
  224.  ****************************************************************************/
  225.  
  226. extern void main ( int argc, PCHAR argv[] )
  227. {
  228.  /***************************************************************************
  229.   * Local Declarations                                *
  230.   ***************************************************************************/
  231.  
  232.   HELPINIT HelpInit =
  233.   {
  234.     sizeof ( HELPINIT ),
  235.     0L,
  236.     NULL,
  237.     MAKEP ( 0xFFFF, ID_MAIN ),
  238.     0,
  239.     0,
  240.     0,
  241.     0,
  242.     NULL,
  243.     CMIC_HIDE_PANEL_ID,
  244.     "MEMSIZE.HLP"
  245.   } ;
  246.  
  247.   CHAR Error [200] ;
  248.   FRAMECDATA fcdata ;
  249.   HAB hAB ;
  250.   CHAR HelpTitle [80] ;
  251.   HMQ hMQ ;
  252.   HWND hwndClient ;
  253.   HWND hwndFrame ;
  254.   HWND hwndHelp ;
  255.   HMODULE Library ;
  256.   PARMS Parms ;
  257.   QMSG qmsg ;
  258.   BOOL Reset ;
  259.   CHAR ResetCommand [40] ;
  260.   CHAR Title [80] ;
  261.  
  262.  /***************************************************************************
  263.   * Initialize for PM.    Abort if unable to do so.                *
  264.   ***************************************************************************/
  265.  
  266.   hAB = WinInitialize ( 0 ) ;
  267.   if ( hAB == NULL )
  268.     return ;
  269.  
  270.  /***************************************************************************
  271.   * Create the application message queue.  Abort if unable to do so.        *
  272.   ***************************************************************************/
  273.  
  274.   hMQ = WinCreateMsgQueue ( hAB, 0 ) ;
  275.   if ( hMQ == NULL )
  276.   {
  277.     WinTerminate ( hAB ) ;
  278.     return ;
  279.   }
  280.  
  281.  /***************************************************************************
  282.   * Now WIN and GPI calls will work.  Open the language DLL.            *
  283.   ***************************************************************************/
  284.  
  285.   if ( DosLoadModule ( Error, sizeof(Error), "MEMSIZE", &Library ) )
  286.   {
  287.     Debug ( HWND_DESKTOP, "ERROR: Unable to load MEMSIZE.DLL: %s", Error ) ;
  288.     WinDestroyMsgQueue ( hMQ ) ;
  289.     WinTerminate ( hAB ) ;
  290.     return ;
  291.   }
  292.  
  293.  /***************************************************************************
  294.   * Register the window class.                            *
  295.   ***************************************************************************/
  296.  
  297.   if ( NOT WinRegisterClass ( hAB, CLASS_NAME, MessageProcessor,
  298.     CS_MOVENOTIFY, sizeof(PVOID) ) )
  299.   {
  300.     CHAR Message [200] ;
  301.     char Title [80] ;
  302.  
  303.     WinLoadString ( hAB, Library, IDS_TITLE,
  304.       sizeof(Title), Title ) ;
  305.     WinLoadString ( hAB, Library, IDS_ERROR_WINREGISTERCLASS,
  306.       sizeof(Message), Message ) ;
  307.     WinMessageBox ( HWND_DESKTOP, HWND_DESKTOP, Message,
  308.       Title, 0, MB_ENTER | MB_ICONEXCLAMATION ) ;
  309.  
  310.     WinDestroyMsgQueue ( hMQ ) ;
  311.     WinTerminate ( hAB ) ;
  312.     return ;
  313.   }
  314.  
  315.  /***************************************************************************
  316.   * Decipher command-line parameters.                        *
  317.   ***************************************************************************/
  318.  
  319.   WinLoadString ( hAB, Library, IDS_PARMS_RESET, sizeof(ResetCommand), ResetCommand ) ;
  320.   Reset = FALSE ;
  321.  
  322.   while ( --argc )
  323.   {
  324.     argv ++ ;
  325.     strupr ( *argv ) ;
  326.     if ( *argv[0] == '?' )
  327.     {
  328.       CHAR Message [200] ;
  329.       CHAR Title [80] ;
  330.  
  331.       WinLoadString ( hAB, Library, IDS_TITLE,
  332.     sizeof(Title), Title ) ;
  333.       WinLoadString ( hAB, Library, IDS_PARAMETERLIST,
  334.     sizeof(Message), Message ) ;
  335.       WinMessageBox ( HWND_DESKTOP, HWND_DESKTOP, Message,
  336.     Title, 0, MB_ENTER | MB_NOICON ) ;
  337.  
  338.       WinDestroyMsgQueue ( hMQ ) ;
  339.       WinTerminate ( hAB ) ;
  340.       return ;
  341.     }
  342.  
  343.     if ( !strcmp ( *argv, ResetCommand ) )
  344.     {
  345.       Reset = TRUE ;
  346.       continue ;
  347.     }
  348.  
  349.     {
  350.       CHAR Format [200] ;
  351.       CHAR Message [200] ;
  352.       CHAR Title [80] ;
  353.  
  354.       WinLoadString ( hAB, Library, IDS_TITLE,
  355.     sizeof(Title), Title ) ;
  356.       WinLoadString ( hAB, Library, IDS_ERROR_INVALIDPARM,
  357.     sizeof(Format), Format ) ;
  358.       sprintf ( Message, Format, *argv ) ;
  359.       WinMessageBox ( HWND_DESKTOP, HWND_DESKTOP, Message,
  360.     Title, 0, MB_ENTER | MB_ICONEXCLAMATION ) ;
  361.  
  362.       WinDestroyMsgQueue ( hMQ ) ;
  363.       WinTerminate ( hAB ) ;
  364.       return ;
  365.     }
  366.   }
  367.  
  368.  /***************************************************************************
  369.   * If we're going to reset the program's profile, do it now.               *
  370.   ***************************************************************************/
  371.  
  372.   if ( Reset )
  373.   {
  374.     PrfWriteProfileData ( HINI_USERPROFILE, PROGRAM_NAME, NULL, NULL, 0 ) ;
  375.   }
  376.  
  377.  /***************************************************************************
  378.   * Create the help instance.                            *
  379.   ***************************************************************************/
  380.  
  381.   WinLoadString ( hAB, Library, IDS_HELPTITLE, sizeof(HelpTitle), HelpTitle ) ;
  382.   HelpInit.pszHelpWindowTitle = HelpTitle ;
  383.  
  384.   hwndHelp = WinCreateHelpInstance ( hAB, &HelpInit ) ;
  385.  
  386.   if ( hwndHelp == NULL )
  387.   {
  388.     CHAR Message [200] ;
  389.     char Title [80] ;
  390.  
  391.     WinLoadString ( hAB, Library, IDS_TITLE,
  392.       sizeof(Title), Title ) ;
  393.     WinLoadString ( hAB, Library, IDS_ERROR_WINCREATEHELPINSTANCE,
  394.       sizeof(Message), Message ) ;
  395.     WinMessageBox ( HWND_DESKTOP, HWND_DESKTOP, Message,
  396.       Title, 0, MB_ENTER | MB_ICONEXCLAMATION ) ;
  397.   }
  398.  
  399.  /***************************************************************************
  400.   * Create the frame window.                            *
  401.   ***************************************************************************/
  402.  
  403.   fcdata.cb = sizeof(fcdata) ;
  404.   fcdata.flCreateFlags =
  405.     FCF_TITLEBAR | FCF_SYSMENU | FCF_BORDER |
  406.       FCF_ICON | FCF_MINBUTTON | FCF_NOBYTEALIGN | FCF_ACCELTABLE ;
  407.   fcdata.hmodResources = 0 ;
  408.   fcdata.idResources   = ID_MAIN ;
  409.  
  410.   hwndFrame = WinCreateWindow
  411.   (
  412.     HWND_DESKTOP,
  413.     WC_FRAME,
  414.     "",
  415.     0,
  416.     0, 0, 0, 0,
  417.     HWND_DESKTOP,
  418.     HWND_TOP,
  419.     ID_MAIN,
  420.     &fcdata,
  421.     NULL
  422.   ) ;
  423.  
  424.   if ( hwndFrame == NULL )
  425.   {
  426.     CHAR Message [200] ;
  427.     char Title [80] ;
  428.  
  429.     WinLoadString ( hAB, Library, IDS_TITLE,
  430.       sizeof(Title), Title ) ;
  431.     WinLoadString ( hAB, Library, IDS_ERROR_WINCREATEFRAME,
  432.       sizeof(Message), Message ) ;
  433.     WinMessageBox ( HWND_DESKTOP, HWND_DESKTOP, Message,
  434.       Title, 0, MB_ENTER | MB_ICONEXCLAMATION ) ;
  435.  
  436.     WinDestroyMsgQueue ( hMQ ) ;
  437.     WinTerminate ( hAB ) ;
  438.     return ;
  439.   }
  440.  
  441.  /***************************************************************************
  442.   * Set the title.                                *
  443.   ***************************************************************************/
  444.  
  445.   WinLoadString ( hAB, Library, IDS_TITLE, sizeof(Title), Title ) ;
  446.   WinSetWindowText ( hwndFrame, Title ) ;
  447.  
  448.  /***************************************************************************
  449.   * Associate the help instance with the frame window.                *
  450.   ***************************************************************************/
  451.  
  452.   if ( hwndHelp )
  453.   {
  454.     WinAssociateHelpInstance ( hwndHelp, hwndFrame ) ;
  455.   }
  456.  
  457.  /***************************************************************************
  458.   * Create client window.  If this fails, destroy frame and return.        *
  459.   ***************************************************************************/
  460.  
  461.   Parms.hAB = hAB ;
  462.   Parms.Library = Library ;
  463.  
  464.   hwndClient = WinCreateWindow
  465.   (
  466.     hwndFrame,
  467.     CLASS_NAME,
  468.     "",
  469.     0,
  470.     0, 0, 0, 0,
  471.     hwndFrame,
  472.     HWND_BOTTOM,
  473.     FID_CLIENT,
  474.     &Parms,
  475.     NULL
  476.   ) ;
  477.  
  478.   if ( hwndClient == NULL )
  479.   {
  480.     CHAR Message [200] ;
  481.     char Title [80] ;
  482.  
  483.     WinLoadString ( hAB, Library, IDS_TITLE,
  484.       sizeof(Title), Title ) ;
  485.     WinLoadString ( hAB, Library, IDS_ERROR_WINCREATEWINDOW,
  486.       sizeof(Message), Message ) ;
  487.     WinMessageBox ( HWND_DESKTOP, HWND_DESKTOP, Message,
  488.       Title, 0, MB_ENTER | MB_ICONEXCLAMATION ) ;
  489.  
  490.     WinDestroyWindow ( hwndFrame ) ;
  491.     WinDestroyMsgQueue ( hMQ ) ;
  492.     WinTerminate ( hAB ) ;
  493.     return ;
  494.   }
  495.  
  496.  /***************************************************************************
  497.   * Wait for and process messages to the window's queue.  Terminate         *
  498.   *   when the WM_QUIT message is received.                    *
  499.   ***************************************************************************/
  500.  
  501.   while ( WinGetMsg ( hAB, &qmsg, NULL, 0, 0 ) )
  502.   {
  503.     WinDispatchMsg ( hAB, &qmsg ) ;
  504.   }
  505.  
  506.  /***************************************************************************
  507.   * Destroy the window.                             *
  508.   ***************************************************************************/
  509.  
  510.   WinDestroyWindow ( hwndFrame ) ;
  511.  
  512.  /***************************************************************************
  513.   * If help instance has been created, get rid of it.                *
  514.   ***************************************************************************/
  515.  
  516.   if ( hwndHelp )
  517.   {
  518.     WinDestroyHelpInstance ( hwndHelp ) ;
  519.   }
  520.  
  521.  /***************************************************************************
  522.   * Release the library, if one's been loaded.                              *
  523.   ***************************************************************************/
  524.  
  525.   if ( Library )
  526.   {
  527.     DosFreeModule ( Library ) ;
  528.   }
  529.  
  530.  /***************************************************************************
  531.   * Discard all that was requested of the system and terminate.         *
  532.   ***************************************************************************/
  533.  
  534.   WinDestroyMsgQueue ( hMQ ) ;
  535.  
  536.   WinTerminate ( hAB ) ;
  537. }
  538.  
  539. /****************************************************************************
  540.  *                                        *
  541.  *    Window Message Processor                        *
  542.  *                                        *
  543.  ****************************************************************************/
  544.  
  545. static MRESULT EXPENTRY MessageProcessor
  546. (
  547.   HWND hwnd,
  548.   USHORT msg,
  549.   MPARAM mp1,
  550.   MPARAM mp2
  551. )
  552. {
  553.  /***************************************************************************
  554.   * Local Declarations                                *
  555.   ***************************************************************************/
  556.  
  557.   static METHOD Methods [] =
  558.   {
  559.     { WM_CREATE,        Create            },
  560.     { WM_DESTROY,        Destroy         },
  561.     { WM_SIZE,            Size            },
  562.     { WM_MOVE,            Size            },
  563.     { WM_SAVEAPPLICATION,    SaveApplication     },
  564.     { WM_PAINT,         Paint            },
  565.     { WM_BUTTON1DOWN,        ButtonDown        },
  566.     { WM_BUTTON2DOWN,        ButtonDown        },
  567.     { WM_BUTTON1DBLCLK,     ButtonDblClick        },
  568.     { WM_BUTTON2DBLCLK,     ButtonDblClick        },
  569.     { WM_PRESPARAMCHANGED,    PresParamChanged    },
  570.     { WM_SYSCOLORCHANGE,    SysColorChange        },
  571.     { WM_COMMAND,        Command         },
  572.     { HM_QUERY_KEYS_HELP,    QueryKeysHelp        },
  573.     { HM_ERROR,         HelpError        },
  574.     { HM_EXT_HELP_UNDEFINED,    ExtHelpUndefined    },
  575.     { HM_HELPSUBITEM_NOT_FOUND, HelpSubitemNotFound },
  576.     { WM_REFRESH,        Refresh         }
  577.   } ;
  578.  
  579.  /***************************************************************************
  580.   * Dispatch the message according to the method table and return the        *
  581.   *   result.  Any messages not defined above get handled by the system     *
  582.   *   default window processor.                         *
  583.   ***************************************************************************/
  584.  
  585.   return ( DispatchMessage ( hwnd, msg, mp1, mp2, Methods, sizeof(Methods)/sizeof(Methods[0]), WinDefWindowProc ) ) ;
  586. }
  587.  
  588. /****************************************************************************
  589.  *                                        *
  590.  *    Create the main window.                         *
  591.  *                                        *
  592.  ****************************************************************************/
  593.  
  594. static MRESULT APIENTRY Create
  595. (
  596.   HWND hwnd,
  597.   USHORT msg,
  598.   MPARAM mp1,
  599.   MPARAM mp2
  600. )
  601. {
  602.  /***************************************************************************
  603.   *                Declarations                    *
  604.   ***************************************************************************/
  605.  
  606.   static MENUITEM MenuItems [] =
  607.   {
  608.     { MIT_END, MIS_TEXT,      0, IDM_SAVE_APPLICATION, NULL, 0 },
  609.     { MIT_END, MIS_TEXT,      0, IDM_RESET_DEFAULTS,   NULL, 0 },
  610.     { MIT_END, MIS_TEXT,      0, IDM_HIDE_CONTROLS,    NULL, 0 },
  611.     { MIT_END, MIS_TEXT,      0, IDM_SET_TIMER,        NULL, 0 },
  612.     { MIT_END, MIS_SUBMENU,   0, IDM_DISPLAY_ITEMS,    NULL, 0 },
  613.   } ;
  614.  
  615.   static MENUITEM MenuSeparator =
  616.     { MIT_END, MIS_SEPARATOR, 0, 0, NULL, 0 } ;
  617.  
  618.   static MENUITEM MenuAbout =
  619.     { MIT_END, MIS_TEXT, 0, IDM_ABOUT, NULL, 0 } ;
  620.  
  621.   static MENUITEM MenuHelp =
  622.     { MIT_END, MIS_HELP, 0, 0, NULL, 0 } ;
  623.  
  624.   static MENUITEM MenuItem =
  625.     { MIT_END, MIS_TEXT, 0, 0, NULL, 0 } ;
  626.  
  627.   char AboutText [80] ;
  628.   PDATA Data ;
  629.   char HelpText [80] ;
  630.   HPS hPS ;
  631.   HWND hwndFrame ;
  632.   SHORT i ;
  633.   PIDLE_PARMS IdleParms ;
  634.   PMONITOR_PARMS MonitorParms ;
  635.   PPARMS Parms ;
  636.   RECTL Rectangle ;
  637.   ULONG Size ;
  638.   PCHAR Swappath ;
  639.   char Title [80] ;
  640.  
  641.  /***************************************************************************
  642.   * Allocate instance data.                            *
  643.   ***************************************************************************/
  644.  
  645.   Data = malloc ( sizeof(DATA) ) ;
  646.  
  647.   WinSetWindowPtr ( hwnd, QWL_USER, Data ) ;
  648.  
  649.  /***************************************************************************
  650.   * Grab any parameters from the WM_CREATE message.                *
  651.   ***************************************************************************/
  652.  
  653.   Parms = (PPARMS) PVOIDFROMMP ( mp1 ) ;
  654.  
  655.   Data->hAB = Parms->hAB ;
  656.   Data->Library = Parms->Library ;
  657.  
  658.  /***************************************************************************
  659.   * Get profile data.                                *
  660.   ***************************************************************************/
  661.  
  662.   GetProfile ( Data->hAB, Data->Library, &Data->Profile ) ;
  663.  
  664.  /***************************************************************************
  665.   * Get country information.                            *
  666.   ***************************************************************************/
  667.  
  668.   {
  669.     COUNTRYCODE CountryCode ;
  670.     USHORT Count ;
  671.     USHORT Status ;
  672.  
  673.     CountryCode.country = 0 ;
  674.     CountryCode.codepage = 0 ;
  675.  
  676.     Status = DosGetCtryInfo ( sizeof(Data->CountryInfo), &CountryCode,
  677.       &Data->CountryInfo, &Count ) ;
  678.     if ( Status )
  679.     {
  680.       char Message [80] ;
  681.       WinLoadMessage ( Data->hAB, Data->Library, IDS_ERROR_DOSGETCTRYINFO,
  682.     sizeof(Message), Message ) ;
  683.       Debug ( hwnd, Message, Status ) ;
  684.       Data->CountryInfo.fsDateFmt = DATEFMT_MM_DD_YY ;
  685.       Data->CountryInfo.fsTimeFmt = 0 ;
  686.       Data->CountryInfo.szDateSeparator[0] = '/' ;
  687.       Data->CountryInfo.szDateSeparator[1] = 0 ;
  688.       Data->CountryInfo.szTimeSeparator[0] = ':' ;
  689.       Data->CountryInfo.szTimeSeparator[1] = 0 ;
  690.       Data->CountryInfo.szThousandsSeparator[0] = ',' ;
  691.       Data->CountryInfo.szThousandsSeparator[1] = 0 ;
  692.     }
  693.   }
  694.  
  695.  /***************************************************************************
  696.   * Get the control window handles.                        *
  697.   ***************************************************************************/
  698.  
  699.   hwndFrame = WinQueryWindow ( hwnd, QW_PARENT, FALSE ) ;
  700.  
  701.   Data->hwndSysMenu  = WinWindowFromID ( hwndFrame, FID_SYSMENU  ) ;
  702.   Data->hwndTitleBar = WinWindowFromID ( hwndFrame, FID_TITLEBAR ) ;
  703.   Data->hwndMinMax   = WinWindowFromID ( hwndFrame, FID_MINMAX   ) ;
  704.  
  705.  /***************************************************************************
  706.   * Create the submenu window for Display Items.                *
  707.   ***************************************************************************/
  708.  
  709.   {
  710.     MENUITEM MenuItem ;
  711.     HWND hwndSysSubMenu ;
  712.     HWND hwndSubMenu ;
  713.     SHORT idSysMenu ;
  714.  
  715.     idSysMenu = SHORT1FROMMR ( WinSendMsg ( Data->hwndSysMenu, MM_ITEMIDFROMPOSITION, NULL, NULL ) ) ;
  716.     WinSendMsg ( Data->hwndSysMenu, MM_QUERYITEM, MPFROM2SHORT(idSysMenu,FALSE), MPFROMP(&MenuItem) ) ;
  717.     hwndSysSubMenu = MenuItem.hwndSubMenu ;
  718.  
  719.     hwndSubMenu = WinCreateWindow ( hwndSysSubMenu, WC_MENU, "",
  720.       WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  721.       0, 0, 0, 0, hwndSysSubMenu, HWND_TOP, IDM_DISPLAY_ITEMS, NULL, NULL ) ;
  722.  
  723.     MenuItems[IDM_DISPLAY_ITEMS-MenuItems[0].id].hwndSubMenu = hwndSubMenu ;
  724.   }
  725.  
  726.  /***************************************************************************
  727.   * Add basic extensions to the system menu.                    *
  728.   ***************************************************************************/
  729.  
  730.   AddSysMenuItem ( hwndFrame, &MenuSeparator, NULL ) ;
  731.  
  732.   for ( i=0; i<sizeof(MenuItems)/sizeof(MenuItems[0]); i++ )
  733.   {
  734.     char MenuText [80] ;
  735.     WinLoadString ( Data->hAB, Data->Library, i+IDS_SAVE_APPLICATION, sizeof(MenuText), MenuText ) ;
  736.     AddSysMenuItem ( hwndFrame, MenuItems+i, MenuText ) ;
  737.   }
  738.  
  739.  /***************************************************************************
  740.   * Add display items as options to the system menu.                *
  741.   ***************************************************************************/
  742.  
  743.   for ( i=0; i<Data->Profile.ItemCount; i++ )
  744.   {
  745.     PITEM Item = & Data->Profile.Items [i] ;
  746.  
  747.     MenuItem.id = Item->MenuId ;
  748.  
  749.     AddSysSubMenuItem ( hwndFrame, IDM_DISPLAY_ITEMS, &MenuItem, Item->MenuOption ) ;
  750.  
  751.     CheckMenuItem ( hwndFrame, FID_SYSMENU, Item->MenuId, Item->Flag ) ;
  752.   }
  753.  
  754.  /***************************************************************************
  755.   * Add 'About' to the system menu.                        *
  756.   ***************************************************************************/
  757.  
  758.   AddSysMenuItem ( hwndFrame, &MenuSeparator, NULL ) ;
  759.   WinLoadString ( Data->hAB, Data->Library, IDS_ABOUT, sizeof(AboutText), AboutText ) ;
  760.   AddSysMenuItem ( hwndFrame, &MenuAbout, AboutText ) ;
  761.  
  762.  /***************************************************************************
  763.   * Add 'Help' to the system menu.                        *
  764.   ***************************************************************************/
  765.  
  766.   WinLoadString ( Data->hAB, Data->Library, IDS_HELP, sizeof(HelpText), HelpText ) ;
  767.   AddSysMenuItem ( hwndFrame, &MenuHelp, HelpText ) ;
  768.  
  769.  /***************************************************************************
  770.   * Get the SWAPPATH statement from CONFIG.SYS.                 *
  771.   ***************************************************************************/
  772.  
  773.   Swappath = ScanSystemConfig ( "SWAPPATH" ) ;
  774.  
  775.   if ( Swappath == NULL )
  776.   {
  777.     Swappath = "C:\\OS2\\SYSTEM 0" ;
  778.   }
  779.  
  780.   strupr ( Swappath ) ;
  781.  
  782.   sscanf ( Swappath, "%s %i", Data->SwapPath, &Data->MinFree ) ;
  783.  
  784.  /***************************************************************************
  785.   * Find out where the spool work directory is.                 *
  786.   ***************************************************************************/
  787.  
  788.   Data->SpoolPath = NULL ;
  789.  
  790.   if ( PrfQueryProfileSize ( HINI_PROFILE, "PM_SPOOLER", "DIR", &Size ) )
  791.   {
  792.     Data->SpoolPath = malloc ( (int)Size ) ;
  793.     if ( Data->SpoolPath )
  794.     {
  795.       if ( PrfQueryProfileData ( HINI_PROFILE, "PM_SPOOLER", "DIR", Data->SpoolPath, &Size ) )
  796.       {
  797.     BYTE *p ;
  798.     p = strchr ( Data->SpoolPath, ';' ) ;
  799.     if ( p )
  800.     {
  801.       *p = 0 ;
  802.     }
  803.       }
  804.       else
  805.       {
  806.     free ( Data->SpoolPath ) ;
  807.     Data->SpoolPath = FALSE ;
  808.       }
  809.     }
  810.   }
  811.  
  812.  /***************************************************************************
  813.   * Start the load meter.                            *
  814.   ***************************************************************************/
  815.  
  816.   Data->IdleCounter = 0 ;
  817.  
  818.   IdleParms = malloc ( sizeof(*IdleParms) ) ;
  819.   IdleParms->Counter = & Data->IdleCounter ;
  820.   Data->IdleLoopTID = _beginthread ( IdleLoopThread, NULL, 8192, IdleParms ) ;
  821.  
  822.   if ( NOT Data->Profile.Items[ITEM_CPULOAD].Flag )
  823.   {
  824.     DosSuspendThread ( Data->IdleLoopTID ) ;
  825.   }
  826.  
  827.   MonitorParms = malloc ( sizeof(*MonitorParms) ) ;
  828.   MonitorParms->Counter = & Data->IdleCounter ;
  829.   MonitorParms->Interval = & Data->Profile.TimerInterval ;
  830.   MonitorParms->Owner = hwnd ;
  831.   Data->MonitorLoopTID = _beginthread ( MonitorLoopThread, NULL, 8192, MonitorParms ) ;
  832.  
  833.  /***************************************************************************
  834.   * Add the program to the system task list.                    *
  835.   ***************************************************************************/
  836.  
  837.   WinLoadString ( Data->hAB, Data->Library, IDS_TITLE, sizeof(Title), Title ) ;
  838.   Add2TaskList ( hwndFrame, Title ) ;
  839.  
  840.  /***************************************************************************
  841.   * Position & size the window.  For some reason, we must move and size     *
  842.   *   the window to the saved position before applying the resizing        *
  843.   *   function as fine-tuning.    Maybe the positioning request fails if        *
  844.   *   the window has no size?                            *
  845.   ***************************************************************************/
  846.  
  847.   WinSetWindowPos ( hwndFrame, NULL,
  848.     Data->Profile.Position.x, Data->Profile.Position.y,
  849.     Data->Profile.Position.cx, Data->Profile.Position.cy,
  850.     SWP_SIZE | SWP_MOVE ) ;
  851.  
  852.   ResizeWindow ( hwnd, &Data->Profile ) ;
  853.  
  854.  /***************************************************************************
  855.   * Hide the controls if so configured.                     *
  856.   ***************************************************************************/
  857.  
  858.   if ( Data->Profile.HideControls )
  859.   {
  860.     HideControls
  861.     (
  862.       TRUE,
  863.       hwndFrame,
  864.       Data->hwndSysMenu,
  865.       Data->hwndTitleBar,
  866.       Data->hwndMinMax
  867.     ) ;
  868.  
  869.     CheckMenuItem ( hwndFrame, FID_SYSMENU, IDM_HIDE_CONTROLS, Data->Profile.HideControls ) ;
  870.   }
  871.  
  872.  /***************************************************************************
  873.   * Get the saved presentation parameters and reinstate them.            *
  874.   ***************************************************************************/
  875.  
  876.   if ( Data->Profile.fFontNameSize )
  877.   {
  878.     WinSetPresParam ( hwnd, PP_FONTNAMESIZE,
  879.       strlen(Data->Profile.FontNameSize)+1, Data->Profile.FontNameSize ) ;
  880.   }
  881.  
  882.   if ( Data->Profile.fBackColor )
  883.   {
  884.     WinSetPresParam ( hwnd, PP_BACKGROUNDCOLOR,
  885.       sizeof(Data->Profile.BackColor), &Data->Profile.BackColor ) ;
  886.   }
  887.  
  888.   if ( Data->Profile.fTextColor )
  889.   {
  890.     WinSetPresParam ( hwnd, PP_FOREGROUNDCOLOR,
  891.       sizeof(Data->Profile.TextColor), &Data->Profile.TextColor ) ;
  892.   }
  893.  
  894.  /***************************************************************************
  895.   * Determine our font size.                            *
  896.   ***************************************************************************/
  897.  
  898.   hPS = WinGetPS ( hwnd ) ;
  899.   WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  900.   WinDrawText ( hPS, 1, " ", &Rectangle, 0L, 0L, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  901.   Data->Width  = Rectangle.xRight - Rectangle.xLeft ;
  902.   Data->Height = Rectangle.yTop - Rectangle.yBottom ;
  903.   WinReleasePS ( hPS ) ;
  904.  
  905.  /***************************************************************************
  906.   * Now that the window's in order, make it visible.                        *
  907.   ***************************************************************************/
  908.  
  909.   WinShowWindow ( hwndFrame, TRUE ) ;
  910.  
  911.  /***************************************************************************
  912.   * Success?  Return no error.                            *
  913.   ***************************************************************************/
  914.  
  915.   return ( 0 ) ;
  916.  
  917.   hwnd = hwnd ;
  918.   msg = msg ;
  919.   mp1 = mp1 ;
  920.   mp2 = mp2 ;
  921. }
  922.  
  923. /****************************************************************************
  924.  *                                        *
  925.  *    Destroy main window.                            *
  926.  *                                        *
  927.  ****************************************************************************/
  928.  
  929. static MRESULT APIENTRY Destroy
  930. (
  931.   HWND hwnd,
  932.   USHORT msg,
  933.   MPARAM mp1,
  934.   MPARAM mp2
  935. )
  936. {
  937.  /***************************************************************************
  938.   *                Declarations                    *
  939.   ***************************************************************************/
  940.  
  941.   PDATA Data ;
  942.  
  943.  /***************************************************************************
  944.   * Find the instance data.                            *
  945.   ***************************************************************************/
  946.  
  947.   Data = (PDATA) WinQueryWindowPtr ( hwnd, QWL_USER ) ;
  948.  
  949.  /***************************************************************************
  950.   * Suspend the CPU load threads.                        *
  951.   ***************************************************************************/
  952.  
  953.  /***************************************************************************
  954.   * Release the instance memory.                        *
  955.   ***************************************************************************/
  956.  
  957.   free ( Data ) ;
  958.  
  959.  /***************************************************************************
  960.   * We're done.                                                             *
  961.   ***************************************************************************/
  962.  
  963.   return ( MRFROMSHORT ( 0 ) ) ;
  964.  
  965.   hwnd = hwnd ;  msg = msg ;  mp1 = mp1 ;  mp2 = mp2 ;
  966. }
  967.  
  968. /****************************************************************************
  969.  *                                        *
  970.  *    Process window resize message.                        *
  971.  *                                        *
  972.  ****************************************************************************/
  973.  
  974. static MRESULT APIENTRY Size
  975. (
  976.   HWND hwnd,
  977.   USHORT msg,
  978.   MPARAM mp1,
  979.   MPARAM mp2
  980. )
  981. {
  982.  /***************************************************************************
  983.   *                Declarations                    *
  984.   ***************************************************************************/
  985.  
  986.   PDATA Data ;
  987.  
  988.   HWND hwndFrame ;
  989.   SWP Position ;
  990.  
  991.  /***************************************************************************
  992.   * Find the instance data.                            *
  993.   ***************************************************************************/
  994.  
  995.   Data = (PDATA) WinQueryWindowPtr ( hwnd, QWL_USER ) ;
  996.  
  997.  /***************************************************************************
  998.   * Find out the window's new position and size.                            *
  999.   ***************************************************************************/
  1000.  
  1001.   hwndFrame = WinQueryWindow ( hwnd, QW_PARENT, FALSE ) ;
  1002.  
  1003.   WinQueryWindowPos ( hwndFrame, &Position ) ;
  1004.  
  1005.   if ( NOT ( Position.fs & SWP_MINIMIZE )
  1006.     AND NOT ( Position.fs & SWP_MAXIMIZE ) )
  1007.   {
  1008.     Data->Profile.Position.x = Position.x ;
  1009.     Data->Profile.Position.y = Position.y ;
  1010.  
  1011.     Data->Profile.Position.cx = Position.cx ;
  1012.     Data->Profile.Position.cy = Position.cy ;
  1013.   }
  1014.  
  1015.   Data->Profile.Position.fs = Position.fs ;
  1016.  
  1017.  /***************************************************************************
  1018.   * We're done.                                                             *
  1019.   ***************************************************************************/
  1020.  
  1021.   return ( 0 ) ;
  1022.  
  1023.   hwnd = hwnd ;
  1024.   msg = msg ;
  1025.   mp1 = mp1 ;
  1026.   mp2 = mp2 ;
  1027. }
  1028.  
  1029. /****************************************************************************
  1030.  *                                        *
  1031.  *    Process SAVE APPLICATION message.                    *
  1032.  *                                        *
  1033.  ****************************************************************************/
  1034.  
  1035. static MRESULT APIENTRY SaveApplication
  1036. (
  1037.   HWND hwnd,
  1038.   USHORT msg,
  1039.   MPARAM mp1,
  1040.   MPARAM mp2
  1041. )
  1042. {
  1043.  /***************************************************************************
  1044.   *                Declarations                    *
  1045.   ***************************************************************************/
  1046.  
  1047.   PDATA Data ;
  1048.  
  1049.  /***************************************************************************
  1050.   * Find the instance data.                            *
  1051.   ***************************************************************************/
  1052.  
  1053.   Data = (PDATA) WinQueryWindowPtr ( hwnd, QWL_USER ) ;
  1054.  
  1055.  /***************************************************************************
  1056.   * Call function to put all profile data out to the system.            *
  1057.   ***************************************************************************/
  1058.  
  1059.   PutProfile ( &Data->Profile ) ;
  1060.  
  1061.  /***************************************************************************
  1062.   * We're done.  Let the system complete default processing.                *
  1063.   ***************************************************************************/
  1064.  
  1065.   return ( WinDefWindowProc ( hwnd, WM_SAVEAPPLICATION, 0, 0 ) ) ;
  1066.  
  1067.   hwnd = hwnd ;
  1068.   msg = msg ;
  1069.   mp1 = mp1 ;
  1070.   mp2 = mp2 ;
  1071. }
  1072.  
  1073. /****************************************************************************
  1074.  *                                        *
  1075.  *    Repaint entire window.                            *
  1076.  *                                        *
  1077.  ****************************************************************************/
  1078.  
  1079. static MRESULT APIENTRY Paint
  1080. (
  1081.   HWND hwnd,
  1082.   USHORT msg,
  1083.   MPARAM mp1,
  1084.   MPARAM mp2
  1085. )
  1086. {
  1087.  /***************************************************************************
  1088.   *                Declarations                    *
  1089.   ***************************************************************************/
  1090.  
  1091.   PDATA Data ;
  1092.   HPS hPS ;
  1093.   RECTL Rectangle ;
  1094.  
  1095.  /***************************************************************************
  1096.   * Find the instance data.                            *
  1097.   ***************************************************************************/
  1098.  
  1099.   Data = (PDATA) WinQueryWindowPtr ( hwnd, QWL_USER ) ;
  1100.  
  1101.  /***************************************************************************
  1102.   * Get presentation space and make it use RGB colors.                *
  1103.   ***************************************************************************/
  1104.  
  1105.   hPS = WinBeginPaint ( hwnd, NULL, NULL ) ;
  1106.   GpiCreateLogColorTable ( hPS, LCOL_RESET, LCOLF_RGB, 0L, 0L, NULL ) ;
  1107.  
  1108.  /***************************************************************************
  1109.   * Clear the window.                                *
  1110.   ***************************************************************************/
  1111.  
  1112.   WinQueryWindowRect ( hwnd, &Rectangle ) ;
  1113.  
  1114.   GpiMove ( hPS, (PPOINTL) &Rectangle.xLeft ) ;
  1115.   GpiSetColor ( hPS, Data->Profile.BackColor ) ;
  1116.   GpiBox ( hPS, DRO_FILL, (PPOINTL) &Rectangle.xRight, 0L, 0L ) ;
  1117.  
  1118.  /***************************************************************************
  1119.   * Release presentation space.                         *
  1120.   ***************************************************************************/
  1121.  
  1122.   WinEndPaint ( hPS ) ;
  1123.  
  1124.  /***************************************************************************
  1125.   * Update the window and return.                        *
  1126.   ***************************************************************************/
  1127.  
  1128.   UpdateWindow ( hwnd, Data, TRUE ) ;
  1129.  
  1130.   return ( 0 ) ;
  1131.  
  1132.   hwnd = hwnd ;
  1133.   msg = msg ;
  1134.   mp1 = mp1 ;
  1135.   mp2 = mp2 ;
  1136. }
  1137.  
  1138. /****************************************************************************
  1139.  *                                        *
  1140.  *    Process commands received by Main Window                *
  1141.  *                                        *
  1142.  ****************************************************************************/
  1143.  
  1144. static MRESULT APIENTRY Command
  1145. (
  1146.   HWND hwnd,
  1147.   USHORT msg,
  1148.   MPARAM mp1,
  1149.   MPARAM mp2
  1150. )
  1151. {
  1152.  /***************************************************************************
  1153.   * Local Declarations                                *
  1154.   ***************************************************************************/
  1155.  
  1156.   static METHOD Methods [] =
  1157.   {
  1158.     { IDM_SAVE_APPLICATION, SaveApplication },
  1159.     { IDM_RESET_DEFAULTS,   ResetDefaults   },
  1160.     { IDM_HIDE_CONTROLS,    HideControlsCmd },
  1161.     { IDM_SET_TIMER,        SetTimer        },
  1162.     { IDM_EXIT,         Exit        },
  1163.     { IDM_ABOUT,        About        },
  1164.   } ;
  1165.  
  1166.   USHORT Command ;
  1167.   PDATA Data ;
  1168.   short i ;
  1169.  
  1170.  /***************************************************************************
  1171.   * Find the instance data.                            *
  1172.   ***************************************************************************/
  1173.  
  1174.   Data = (PDATA) WinQueryWindowPtr ( hwnd, QWL_USER ) ;
  1175.  
  1176.  /***************************************************************************
  1177.   * Process indicated command . . .                        *
  1178.   ***************************************************************************/
  1179.  
  1180.   Command = SHORT1FROMMP ( mp1 ) ;
  1181.  
  1182.  /***************************************************************************
  1183.   * Process display item commands.                        *
  1184.   ***************************************************************************/
  1185.  
  1186.   for ( i=0; i<Data->Profile.ItemCount; i++ )
  1187.   {
  1188.     PITEM Item = & Data->Profile.Items [i] ;
  1189.  
  1190.     if ( Command == Item->MenuId )
  1191.     {
  1192.       HWND hwndFrame = WinQueryWindow ( hwnd, QW_PARENT, FALSE ) ;
  1193.  
  1194.       Item->Flag = Item->Flag ? FALSE : TRUE ;
  1195.  
  1196.       if ( i == ITEM_CPULOAD )
  1197.       {
  1198.     if ( Item->Flag )
  1199.       DosResumeThread ( Data->IdleLoopTID ) ;
  1200.     else
  1201.       DosSuspendThread ( Data->IdleLoopTID ) ;
  1202.       }
  1203.  
  1204.       CheckMenuItem ( hwndFrame, FID_SYSMENU, Item->MenuId, Item->Flag ) ;
  1205.  
  1206.       ResizeWindow ( hwnd, &Data->Profile ) ;
  1207.  
  1208.       return ( MRFROMSHORT ( 0 ) ) ;
  1209.     }
  1210.   }
  1211.  
  1212.  /***************************************************************************
  1213.   * Dispatch all other commands through the method table.            *
  1214.   ***************************************************************************/
  1215.  
  1216.   return ( DispatchMessage ( hwnd, SHORT1FROMMP(mp1), mp1, mp2, Methods, sizeof(Methods)/sizeof(Methods[0]), NULL ) ) ;
  1217.  
  1218.   hwnd = hwnd ;  msg = msg ;  mp1 = mp1 ;  mp2 = mp2 ;
  1219. }
  1220.  
  1221. /****************************************************************************
  1222.  *                                        *
  1223.  *    Process Reset Defaults menu command.                    *
  1224.  *                                        *
  1225.  ****************************************************************************/
  1226.  
  1227. static MRESULT APIENTRY ResetDefaults
  1228.   HWND hwnd, 
  1229.   USHORT msg, 
  1230.   MPARAM mp1, 
  1231.   MPARAM mp2
  1232. )
  1233. {
  1234.  /***************************************************************************
  1235.   * Reset all profile data for this program.                    *
  1236.   ***************************************************************************/
  1237.  
  1238.   PrfWriteProfileData ( HINI_USERPROFILE, PROGRAM_NAME, NULL, NULL, 0 ) ;
  1239.  
  1240.  /***************************************************************************
  1241.   * Reset the program's presentation parameters.                            *
  1242.   ***************************************************************************/
  1243.  
  1244.   WinRemovePresParam ( hwnd, PP_FONTNAMESIZE ) ;
  1245.   WinRemovePresParam ( hwnd, PP_FOREGROUNDCOLOR ) ;
  1246.   WinRemovePresParam ( hwnd, PP_BACKGROUNDCOLOR ) ;
  1247.  
  1248.  /***************************************************************************
  1249.   * Done.                                    *
  1250.   ***************************************************************************/
  1251.  
  1252.   return ( MRFROMSHORT ( 0 ) ) ;
  1253.  
  1254.   hwnd = hwnd ;  msg = msg ;  mp1 = mp1 ;  mp2 = mp2 ;
  1255. }
  1256.  
  1257. /****************************************************************************
  1258.  *                                        *
  1259.  *    Process Hide Controls menu command.                    *
  1260.  *                                        *
  1261.  ****************************************************************************/
  1262.  
  1263. static MRESULT APIENTRY HideControlsCmd
  1264.   HWND hwnd, 
  1265.   USHORT msg, 
  1266.   MPARAM mp1, 
  1267.   MPARAM mp2
  1268. )
  1269. {
  1270.  /***************************************************************************
  1271.   * Local Declarations.                             *
  1272.   ***************************************************************************/
  1273.  
  1274.   PDATA Data ;
  1275.   HWND hwndFrame = WinQueryWindow ( hwnd, QW_PARENT, FALSE ) ;
  1276.  
  1277.  /***************************************************************************
  1278.   * Find the instance data.                            *
  1279.   ***************************************************************************/
  1280.  
  1281.   Data = (PDATA) WinQueryWindowPtr ( hwnd, QWL_USER ) ;
  1282.  
  1283.  /***************************************************************************
  1284.   * Toggle the Hide Controls setting.                        *
  1285.   ***************************************************************************/
  1286.  
  1287.   Data->Profile.HideControls = Data->Profile.HideControls ? FALSE : TRUE ;
  1288.  
  1289.  /***************************************************************************
  1290.   * Go hide the controls, or reveal them, according to the new flag.        *
  1291.   ***************************************************************************/
  1292.  
  1293.   HideControls
  1294.   (
  1295.     Data->Profile.HideControls,
  1296.     WinQueryWindow ( hwnd, QW_PARENT, FALSE ),
  1297.     Data->hwndSysMenu,
  1298.     Data->hwndTitleBar,
  1299.     Data->hwndMinMax
  1300.   ) ;
  1301.  
  1302.  /***************************************************************************
  1303.   * Check or uncheck the menu option.                        *
  1304.   ***************************************************************************/
  1305.  
  1306.   CheckMenuItem ( hwndFrame, FID_SYSMENU, IDM_HIDE_CONTROLS, Data->Profile.HideControls ) ;
  1307.  
  1308.  /***************************************************************************
  1309.   * Done.                                    *
  1310.   ***************************************************************************/
  1311.  
  1312.   return ( MRFROMSHORT ( 0 ) ) ;
  1313.  
  1314.   hwnd = hwnd ;  msg = msg ;  mp1 = mp1 ;  mp2 = mp2 ;
  1315. }
  1316.  
  1317. /****************************************************************************
  1318.  *                                        *
  1319.  *    Process Set Timer menu command.                     *
  1320.  *                                        *
  1321.  ****************************************************************************/
  1322.  
  1323. static MRESULT APIENTRY SetTimer
  1324.   HWND hwnd, 
  1325.   USHORT msg, 
  1326.   MPARAM mp1, 
  1327.   MPARAM mp2
  1328. )
  1329. {
  1330.  /***************************************************************************
  1331.   * Local Declarations.                             *
  1332.   ***************************************************************************/
  1333.  
  1334.   PDATA Data ;
  1335.   SETTIMER_PARMS Parms ;
  1336.  
  1337.  /***************************************************************************
  1338.   * Find the instance data.                            *
  1339.   ***************************************************************************/
  1340.  
  1341.   Data = (PDATA) WinQueryWindowPtr ( hwnd, QWL_USER ) ;
  1342.  
  1343.  /***************************************************************************
  1344.   * Invoke the Set Timer dialog.                        *
  1345.   ***************************************************************************/
  1346.  
  1347.   Parms.id = IDD_SET_TIMER ;
  1348.   Parms.hwndHelp = WinQueryHelpInstance ( hwnd ) ;
  1349.   Parms.TimerInterval = & Data->Profile.TimerInterval ;
  1350.  
  1351.   WinDlgBox ( HWND_DESKTOP, hwnd, SetTimerProcessor,
  1352.     Data->Library, IDD_SET_TIMER, &Parms ) ;
  1353.  
  1354.  /***************************************************************************
  1355.   * Done.                                    *
  1356.   ***************************************************************************/
  1357.  
  1358.   return ( MRFROMSHORT ( 0 ) ) ;
  1359.  
  1360.   hwnd = hwnd ;  msg = msg ;  mp1 = mp1 ;  mp2 = mp2 ;
  1361. }
  1362.  
  1363. /****************************************************************************
  1364.  *                                        *
  1365.  *    Process About menu command.                        *
  1366.  *                                        *
  1367.  ****************************************************************************/
  1368.  
  1369. static MRESULT APIENTRY About
  1370.   HWND hwnd, 
  1371.   USHORT msg, 
  1372.   MPARAM mp1, 
  1373.   MPARAM mp2
  1374. )
  1375. {
  1376.  /***************************************************************************
  1377.   * Local Declarations                                *
  1378.   ***************************************************************************/
  1379.  
  1380.   PDATA Data ;
  1381.   ABOUT_PARMS Parms ;
  1382.  
  1383.  /***************************************************************************
  1384.   * Find the instance data.                            *
  1385.   ***************************************************************************/
  1386.  
  1387.   Data = (PDATA) WinQueryWindowPtr ( hwnd, QWL_USER ) ;
  1388.  
  1389.  /***************************************************************************
  1390.   * Invoke the About dialog.                            *
  1391.   ***************************************************************************/
  1392.  
  1393.   Parms.id = IDD_ABOUT ;
  1394.   Parms.hwndHelp = WinQueryHelpInstance ( hwnd ) ;
  1395.  
  1396.   WinDlgBox ( HWND_DESKTOP, hwnd, AboutProcessor,
  1397.     Data->Library, IDD_ABOUT, &Parms ) ;
  1398.  
  1399.  /***************************************************************************
  1400.   * Done.                                    *
  1401.   ***************************************************************************/
  1402.  
  1403.   return ( MRFROMSHORT ( 0 ) ) ;
  1404.  
  1405.   hwnd = hwnd ;  msg = msg ;  mp1 = mp1 ;  mp2 = mp2 ;
  1406. }
  1407.  
  1408. /****************************************************************************
  1409.  *                                        *
  1410.  *    Process Mouse Button being pressed.                    *
  1411.  *                                        *
  1412.  ****************************************************************************/
  1413.  
  1414. static MRESULT APIENTRY ButtonDown
  1415. (
  1416.   HWND hwnd,
  1417.   USHORT msg,
  1418.   MPARAM mp1,
  1419.   MPARAM mp2
  1420. )
  1421. {
  1422.  /***************************************************************************
  1423.   * Local Declarations                                *
  1424.   ***************************************************************************/
  1425.  
  1426.   PDATA Data ;
  1427.   HWND hwndFrame ;
  1428.   SWP Position ;
  1429.   TRACKINFO TrackInfo ;
  1430.  
  1431.  /***************************************************************************
  1432.   * Find the instance data.                            *
  1433.   ***************************************************************************/
  1434.  
  1435.   Data = (PDATA) WinQueryWindowPtr ( hwnd, QWL_USER ) ;
  1436.  
  1437.  /***************************************************************************
  1438.   * Determine the new window position.                        *
  1439.   ***************************************************************************/
  1440.  
  1441.   memset ( &TrackInfo, 0, sizeof(TrackInfo) ) ;
  1442.  
  1443.   TrackInfo.cxBorder = 1 ;
  1444.   TrackInfo.cyBorder = 1 ;
  1445.   TrackInfo.cxGrid = 1 ;
  1446.   TrackInfo.cyGrid = 1 ;
  1447.   TrackInfo.cxKeyboard = 8 ;
  1448.   TrackInfo.cyKeyboard = 8 ;
  1449.  
  1450.   hwndFrame = WinQueryWindow ( hwnd, QW_PARENT, FALSE ) ;
  1451.  
  1452.   WinQueryWindowPos ( hwndFrame, &Position ) ;
  1453.   TrackInfo.rclTrack.xLeft   = Position.x ;
  1454.   TrackInfo.rclTrack.xRight  = Position.x + Position.cx ;
  1455.   TrackInfo.rclTrack.yBottom = Position.y ;
  1456.   TrackInfo.rclTrack.yTop    = Position.y + Position.cy ;
  1457.  
  1458.   WinQueryWindowPos ( HWND_DESKTOP, &Position ) ;
  1459.   TrackInfo.rclBoundary.xLeft   = Position.x ;
  1460.   TrackInfo.rclBoundary.xRight  = Position.x + Position.cx ;
  1461.   TrackInfo.rclBoundary.yBottom = Position.y ;
  1462.   TrackInfo.rclBoundary.yTop    = Position.y + Position.cy ;
  1463.  
  1464.   TrackInfo.ptlMinTrackSize.x = 0 ;
  1465.   TrackInfo.ptlMinTrackSize.y = 0 ;
  1466.   TrackInfo.ptlMaxTrackSize.x = Position.cx ;
  1467.   TrackInfo.ptlMaxTrackSize.y = Position.cy ;
  1468.  
  1469.   TrackInfo.fs = TF_MOVE | TF_STANDARD | TF_ALLINBOUNDARY ;
  1470.  
  1471.   if ( WinTrackRect ( HWND_DESKTOP, NULL, &TrackInfo ) )
  1472.   {
  1473.     WinSetWindowPos ( hwndFrame, NULL,
  1474.       (SHORT) TrackInfo.rclTrack.xLeft,
  1475.       (SHORT) TrackInfo.rclTrack.yBottom,
  1476.       0, 0, SWP_MOVE ) ;
  1477.   }
  1478.  
  1479.  /***************************************************************************
  1480.   * Return through the default processor, letting window activation        *
  1481.   *   and other system functions occur.                     *
  1482.   ***************************************************************************/
  1483.  
  1484.   return ( WinDefWindowProc ( hwnd, msg, mp1, mp2 ) ) ;
  1485.  
  1486.   hwnd = hwnd ;  msg = msg ;  mp1 = mp1 ;  mp2 = mp2 ;
  1487. }
  1488.  
  1489. /****************************************************************************
  1490.  *                                        *
  1491.  *    Process Mouse Button having been double-clicked.            *
  1492.  *                                        *
  1493.  ****************************************************************************/
  1494.  
  1495. static MRESULT APIENTRY ButtonDblClick
  1496. (
  1497.   HWND hwnd,
  1498.   USHORT msg,
  1499.   MPARAM mp1,
  1500.   MPARAM mp2
  1501. )
  1502. {
  1503.  /***************************************************************************
  1504.   * Send message to self to stop hiding the controls.                *
  1505.   ***************************************************************************/
  1506.  
  1507.   WinPostMsg ( hwnd, WM_COMMAND,
  1508.     MPFROM2SHORT ( IDM_HIDE_CONTROLS, 0 ),
  1509.     MPFROM2SHORT ( CMDSRC_OTHER, TRUE ) ) ;
  1510.  
  1511.  /***************************************************************************
  1512.   * Return through the default processor, letting window activation        *
  1513.   *   and other system functions occur.                     *
  1514.   ***************************************************************************/
  1515.  
  1516.   return ( WinDefWindowProc ( hwnd, msg, mp1, mp2 ) ) ;
  1517.  
  1518.   hwnd = hwnd ;  msg = msg ;  mp1 = mp1 ;  mp2 = mp2 ;
  1519. }
  1520.  
  1521. /****************************************************************************
  1522.  *                                        *
  1523.  *    Process Presentation Parameter Changed notification.            *
  1524.  *                                        *
  1525.  ****************************************************************************/
  1526.  
  1527. static MRESULT APIENTRY PresParamChanged
  1528. (
  1529.   HWND hwnd,
  1530.   USHORT msg,
  1531.   MPARAM mp1,
  1532.   MPARAM mp2
  1533. )
  1534. {
  1535.  /***************************************************************************
  1536.   * Local Declarations                                *
  1537.   ***************************************************************************/
  1538.  
  1539.   PDATA Data ;
  1540.   HPS hPS ;
  1541.   ULONG ppid ;
  1542.   RECTL Rectangle ;
  1543.  
  1544.  /***************************************************************************
  1545.   * Find the instance data.                            *
  1546.   ***************************************************************************/
  1547.  
  1548.   Data = (PDATA) WinQueryWindowPtr ( hwnd, QWL_USER ) ;
  1549.  
  1550.  /***************************************************************************
  1551.   * Get the presentation parameter that changed.                *
  1552.   ***************************************************************************/
  1553.  
  1554.   switch ( LONGFROMMP(mp1) )
  1555.   {
  1556.  
  1557.    /*************************************************************************
  1558.     * If font, note the fact that we now have a font to be saved as        *
  1559.     *    part of the configuration.  Get the font metrics and resize        *
  1560.     *    the window appropriately.                        *
  1561.     *************************************************************************/
  1562.  
  1563.     case PP_FONTNAMESIZE:
  1564.     {
  1565.       if ( WinQueryPresParam ( hwnd, PP_FONTNAMESIZE, 0, &ppid,
  1566.     sizeof(Data->Profile.FontNameSize), &Data->Profile.FontNameSize,
  1567.     0 ) )
  1568.       {
  1569.     Data->Profile.fFontNameSize = TRUE ;
  1570.       }
  1571.       else
  1572.       {
  1573.     strcpy ( Data->Profile.FontNameSize, "" ) ;
  1574.     Data->Profile.fFontNameSize = FALSE ;
  1575.     PrfWriteProfileData ( HINI_USERPROFILE, PROGRAM_NAME, "FontNameSize", NULL, 0 ) ;
  1576.       }
  1577.  
  1578.       hPS = WinGetPS ( hwnd ) ;
  1579.       WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  1580.       WinDrawText ( hPS, 1, " ", &Rectangle, 0L, 0L, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  1581.       Data->Width  = Rectangle.xRight - Rectangle.xLeft ;
  1582.       Data->Height = Rectangle.yTop - Rectangle.yBottom ;
  1583.       WinReleasePS ( hPS ) ;
  1584.       ResizeWindow ( hwnd, &Data->Profile ) ;
  1585.       break ;
  1586.     }
  1587.  
  1588.    /*************************************************************************
  1589.     * If background color, note the fact and repaint the window.        *
  1590.     *************************************************************************/
  1591.  
  1592.     case PP_BACKGROUNDCOLOR:
  1593.     {
  1594.       if ( WinQueryPresParam ( hwnd, PP_BACKGROUNDCOLOR, 0, &ppid,
  1595.     sizeof(Data->Profile.BackColor), &Data->Profile.BackColor, 0 ) )
  1596.       {
  1597.     Data->Profile.fBackColor = TRUE ;
  1598.       }
  1599.       else
  1600.       {
  1601.     Data->Profile.BackColor = WinQuerySysColor ( HWND_DESKTOP, SYSCLR_WINDOW, 0L ) ;
  1602.     Data->Profile.fBackColor = FALSE ;
  1603.     PrfWriteProfileData ( HINI_USERPROFILE, PROGRAM_NAME, "BackgroundColor", NULL, 0 ) ;
  1604.       }
  1605.       WinInvalidateRect ( hwnd, NULL, TRUE ) ;
  1606.       break ;
  1607.     }
  1608.  
  1609.    /*************************************************************************
  1610.     * If foreground color, note the fact and repaint the window.        *
  1611.     *************************************************************************/
  1612.  
  1613.     case PP_FOREGROUNDCOLOR:
  1614.     {
  1615.       if ( WinQueryPresParam ( hwnd, PP_FOREGROUNDCOLOR, 0, &ppid,
  1616.     sizeof(Data->Profile.TextColor), &Data->Profile.TextColor, 0 ) )
  1617.       {
  1618.     Data->Profile.fTextColor = TRUE ;
  1619.       }
  1620.       else
  1621.       {
  1622.     Data->Profile.TextColor = WinQuerySysColor ( HWND_DESKTOP, SYSCLR_OUTPUTTEXT, 0L ) ;
  1623.     Data->Profile.fTextColor = FALSE ;
  1624.     PrfWriteProfileData ( HINI_USERPROFILE, PROGRAM_NAME, "ForegroundColor", NULL, 0 ) ;
  1625.       }
  1626.       WinInvalidateRect ( hwnd, NULL, TRUE ) ;
  1627.       break ;
  1628.     }
  1629.   }
  1630.  
  1631.  /***************************************************************************
  1632.   * Return through the default processor, letting window activation        *
  1633.   *   and other system functions occur.                     *
  1634.   ***************************************************************************/
  1635.  
  1636.   return ( WinDefWindowProc ( hwnd, msg, mp1, mp2 ) ) ;
  1637.  
  1638.   hwnd = hwnd ;  msg = msg ;  mp1 = mp1 ;  mp2 = mp2 ;
  1639. }
  1640.  
  1641. /****************************************************************************
  1642.  *                                        *
  1643.  *    Process System Color Change notification.                *
  1644.  *                                        *
  1645.  ****************************************************************************/
  1646.  
  1647. static MRESULT APIENTRY SysColorChange
  1648. (
  1649.   HWND hwnd,
  1650.   USHORT msg,
  1651.   MPARAM mp1,
  1652.   MPARAM mp2
  1653. )
  1654. {
  1655.  /***************************************************************************
  1656.   * Local Declarations                                *
  1657.   ***************************************************************************/
  1658.  
  1659.   PDATA Data ;
  1660.  
  1661.  /***************************************************************************
  1662.   * Find the instance data.                            *
  1663.   ***************************************************************************/
  1664.  
  1665.   Data = (PDATA) WinQueryWindowPtr ( hwnd, QWL_USER ) ;
  1666.  
  1667.  /***************************************************************************
  1668.   * If we aren't using custom colors, then query for the new defaults.      *
  1669.   ***************************************************************************/
  1670.  
  1671.   if ( NOT Data->Profile.fBackColor )
  1672.   {
  1673.     Data->Profile.BackColor = WinQuerySysColor ( HWND_DESKTOP, SYSCLR_WINDOW, 0L ) ;
  1674.   }
  1675.  
  1676.   if ( NOT Data->Profile.fTextColor )
  1677.   {
  1678.     Data->Profile.TextColor = WinQuerySysColor ( HWND_DESKTOP, SYSCLR_OUTPUTTEXT, 0L ) ;
  1679.   }
  1680.  
  1681.  /***************************************************************************
  1682.   * Return value must be NULL, according to the documentation.            *
  1683.   ***************************************************************************/
  1684.  
  1685.   return ( MRFROMP ( NULL ) ) ;
  1686.  
  1687.   hwnd = hwnd ;  msg = msg ;  mp1 = mp1 ;  mp2 = mp2 ;
  1688. }
  1689.  
  1690. /****************************************************************************
  1691.  *                                        *
  1692.  *    Process Query for Keys Help resource id.                *
  1693.  *                                        *
  1694.  ****************************************************************************/
  1695.  
  1696. static MRESULT APIENTRY QueryKeysHelp
  1697. (
  1698.   HWND hwnd,
  1699.   USHORT msg,
  1700.   MPARAM mp1,
  1701.   MPARAM mp2
  1702. )
  1703. {
  1704.  /***************************************************************************
  1705.   * Simply return the ID of the Keys Help panel.                *
  1706.   ***************************************************************************/
  1707.  
  1708.   return ( (MRESULT) IDM_KEYS_HELP ) ;
  1709.  
  1710.   hwnd = hwnd ;  msg = msg ;  mp1 = mp1 ;  mp2 = mp2 ;
  1711. }
  1712.  
  1713. /****************************************************************************
  1714.  *                                        *
  1715.  *    Process Help Manager Error                        *
  1716.  *                                        *
  1717.  ****************************************************************************/
  1718.  
  1719. static MRESULT APIENTRY HelpError
  1720.   HWND hwnd, 
  1721.   USHORT msg, 
  1722.   MPARAM mp1, 
  1723.   MPARAM mp2
  1724. )
  1725. {
  1726.  /***************************************************************************
  1727.   * Local Declarations                                *
  1728.   ***************************************************************************/
  1729.  
  1730.   static struct
  1731.   {
  1732.     ULONG Error ;
  1733.     USHORT StringId ;
  1734.   }
  1735.   HelpErrors [] =
  1736.   {
  1737.     { HMERR_NO_FRAME_WND_IN_CHAIN,     IDS_HMERR_NO_FRAME_WND_IN_CHAIN },
  1738.     { HMERR_INVALID_ASSOC_APP_WND,     IDS_HMERR_INVALID_ASSOC_APP_WND },
  1739.     { HMERR_INVALID_ASSOC_HELP_INST,   IDS_HMERR_INVALID_ASSOC_HELP_IN },
  1740.     { HMERR_INVALID_DESTROY_HELP_INST, IDS_HMERR_INVALID_DESTROY_HELP_ },
  1741.     { HMERR_NO_HELP_INST_IN_CHAIN,     IDS_HMERR_NO_HELP_INST_IN_CHAIN },
  1742.     { HMERR_INVALID_HELP_INSTANCE_HDL, IDS_HMERR_INVALID_HELP_INSTANCE },
  1743.     { HMERR_INVALID_QUERY_APP_WND,     IDS_HMERR_INVALID_QUERY_APP_WND },
  1744.     { HMERR_HELP_INST_CALLED_INVALID,  IDS_HMERR_HELP_INST_CALLED_INVA },
  1745.     { HMERR_HELPTABLE_UNDEFINE,        IDS_HMERR_HELPTABLE_UNDEFINE    },
  1746.     { HMERR_HELP_INSTANCE_UNDEFINE,    IDS_HMERR_HELP_INSTANCE_UNDEFIN },
  1747.     { HMERR_HELPITEM_NOT_FOUND,        IDS_HMERR_HELPITEM_NOT_FOUND    },
  1748.     { HMERR_INVALID_HELPSUBITEM_SIZE,  IDS_HMERR_INVALID_HELPSUBITEM_S },
  1749.     { HMERR_HELPSUBITEM_NOT_FOUND,     IDS_HMERR_HELPSUBITEM_NOT_FOUND },
  1750.     { HMERR_INDEX_NOT_FOUND,           IDS_HMERR_INDEX_NOT_FOUND       },
  1751.     { HMERR_CONTENT_NOT_FOUND,           IDS_HMERR_CONTENT_NOT_FOUND     },
  1752.     { HMERR_OPEN_LIB_FILE,           IDS_HMERR_OPEN_LIB_FILE           },
  1753.     { HMERR_READ_LIB_FILE,           IDS_HMERR_READ_LIB_FILE           },
  1754.     { HMERR_CLOSE_LIB_FILE,           IDS_HMERR_CLOSE_LIB_FILE        },
  1755.     { HMERR_INVALID_LIB_FILE,           IDS_HMERR_INVALID_LIB_FILE      },
  1756.     { HMERR_NO_MEMORY,               IDS_HMERR_NO_MEMORY           },
  1757.     { HMERR_ALLOCATE_SEGMENT,           IDS_HMERR_ALLOCATE_SEGMENT      },
  1758.     { HMERR_FREE_MEMORY,           IDS_HMERR_FREE_MEMORY           },
  1759.     { HMERR_PANEL_NOT_FOUND,           IDS_HMERR_PANEL_NOT_FOUND       },
  1760.     { HMERR_DATABASE_NOT_OPEN,           IDS_HMERR_DATABASE_NOT_OPEN     },
  1761.     { 0,                   IDS_HMERR_UNKNOWN           }
  1762.   } ;
  1763.  
  1764.   PDATA Data ;
  1765.   ULONG ErrorCode = (ULONG) LONGFROMMP ( mp1 ) ;
  1766.   int Index ;
  1767.   char Message [200] ;
  1768.   char Title [80] ;
  1769.  
  1770.  /***************************************************************************
  1771.   * Find the instance data.                            *
  1772.   ***************************************************************************/
  1773.  
  1774.   Data = (PDATA) WinQueryWindowPtr ( hwnd, QWL_USER ) ;
  1775.  
  1776.  /***************************************************************************
  1777.   * Find the error code in the message table.                    *
  1778.   ***************************************************************************/
  1779.  
  1780.   Index = 0 ;
  1781.   while ( HelpErrors[Index].Error
  1782.     AND ( HelpErrors[Index].Error != ErrorCode ) )
  1783.   {
  1784.     Index ++ ;
  1785.   }
  1786.  
  1787.  /***************************************************************************
  1788.   * Get the message texts.                            *
  1789.   ***************************************************************************/
  1790.  
  1791.   WinLoadString ( Data->hAB, Data->Library, IDS_HMERR, sizeof(Title), Title ) ;
  1792.  
  1793.   WinLoadString ( Data->hAB, Data->Library, HelpErrors[Index].StringId, sizeof(Message), Message ) ;
  1794.  
  1795.  /***************************************************************************
  1796.   * Display the error message.                            *
  1797.   ***************************************************************************/
  1798.  
  1799.   WinMessageBox
  1800.   (
  1801.     HWND_DESKTOP,
  1802.     hwnd,
  1803.     Message,
  1804.     Title,
  1805.     0,
  1806.     MB_OK | MB_WARNING
  1807.   ) ;
  1808.  
  1809.  /***************************************************************************
  1810.   * Return zero, indicating that the message was processed.            *
  1811.   ***************************************************************************/
  1812.  
  1813.   return ( MRFROMSHORT ( 0 ) ) ;
  1814.  
  1815.   hwnd = hwnd ;  msg = msg ;  mp1 = mp1 ;  mp2 = mp2 ;
  1816. }
  1817.  
  1818. /****************************************************************************
  1819.  *                                        *
  1820.  *    Process "Extended Help Undefined" notification                *
  1821.  *                                        *
  1822.  ****************************************************************************/
  1823.  
  1824. static MRESULT APIENTRY ExtHelpUndefined
  1825.   HWND hwnd, 
  1826.   USHORT msg, 
  1827.   MPARAM mp1, 
  1828.   MPARAM mp2
  1829. )
  1830. {
  1831.  /***************************************************************************
  1832.   * Local Declarations                                *
  1833.   ***************************************************************************/
  1834.  
  1835.   PDATA Data ;
  1836.   char Message [200] ;
  1837.   char Title [80] ;
  1838.  
  1839.  /***************************************************************************
  1840.   * Find the instance data.                            *
  1841.   ***************************************************************************/
  1842.  
  1843.   Data = (PDATA) WinQueryWindowPtr ( hwnd, QWL_USER ) ;
  1844.  
  1845.  /***************************************************************************
  1846.   * Get the message texts.                            *
  1847.   ***************************************************************************/
  1848.  
  1849.   WinLoadString ( Data->hAB, Data->Library, IDS_HMERR, sizeof(Title), Title ) ;
  1850.  
  1851.   WinLoadString ( Data->hAB, Data->Library, IDS_HMERR_EXTHELPUNDEFINED, sizeof(Message), Message ) ;
  1852.  
  1853.  /***************************************************************************
  1854.   * Display the error message.                            *
  1855.   ***************************************************************************/
  1856.  
  1857.   WinMessageBox
  1858.   (
  1859.     HWND_DESKTOP,
  1860.     hwnd,
  1861.     Message,
  1862.     Title,
  1863.     0,
  1864.     MB_OK | MB_WARNING
  1865.   ) ;
  1866.  
  1867.  /***************************************************************************
  1868.   * Return zero, indicating that the message was processed.            *
  1869.   ***************************************************************************/
  1870.  
  1871.   return ( MRFROMSHORT ( 0 ) ) ;
  1872.  
  1873.   hwnd = hwnd ;  msg = msg ;  mp1 = mp1 ;  mp2 = mp2 ;
  1874. }
  1875.  
  1876. /****************************************************************************
  1877.  *                                        *
  1878.  *    Process "Help Subitem Not Found" notification                *
  1879.  *                                        *
  1880.  ****************************************************************************/
  1881.  
  1882. static MRESULT APIENTRY HelpSubitemNotFound
  1883.   HWND hwnd, 
  1884.   USHORT msg, 
  1885.   MPARAM mp1, 
  1886.   MPARAM mp2
  1887. )
  1888. {
  1889.  /***************************************************************************
  1890.   * Local Declarations                                *
  1891.   ***************************************************************************/
  1892.  
  1893.   PDATA Data ;
  1894.   int i ;
  1895.   BYTE Format [200] ;
  1896.   BYTE Message [200] ;
  1897.   BYTE Mode [40] ;
  1898.   USHORT Subtopic ;
  1899.   char Title [80] ;
  1900.   USHORT Topic ;
  1901.  
  1902.  /***************************************************************************
  1903.   * Find the instance data.                            *
  1904.   ***************************************************************************/
  1905.  
  1906.   Data = (PDATA) WinQueryWindowPtr ( hwnd, QWL_USER ) ;
  1907.  
  1908.  /***************************************************************************
  1909.   * Get the title text.                             *
  1910.   ***************************************************************************/
  1911.  
  1912.   WinLoadString ( Data->hAB, Data->Library, IDS_HMERR, sizeof(Title), Title ) ;
  1913.  
  1914.  /***************************************************************************
  1915.   * Format the error message.                            *
  1916.   ***************************************************************************/
  1917.  
  1918.   Topic = (USHORT) SHORT1FROMMP ( mp2 ) ;
  1919.   Subtopic = (USHORT) SHORT2FROMMP ( mp2 ) ;
  1920.  
  1921.   i = SHORT1FROMMP ( mp1 ) ;
  1922.  
  1923.   switch ( i )
  1924.   {
  1925.     case HLPM_FRAME:
  1926.       WinLoadString ( Data->hAB, Data->Library, IDS_HELPMODE_FRAME, sizeof(Mode), Mode ) ;
  1927.       break ;
  1928.  
  1929.     case HLPM_MENU:
  1930.       WinLoadString ( Data->hAB, Data->Library, IDS_HELPMODE_MENU, sizeof(Mode), Mode ) ;
  1931.       break ;
  1932.  
  1933.     case HLPM_WINDOW:
  1934.       WinLoadString ( Data->hAB, Data->Library, IDS_HELPMODE_WINDOW, sizeof(Mode), Mode ) ;
  1935.       break ;
  1936.  
  1937.     default:
  1938.       WinLoadString ( Data->hAB, Data->Library, IDS_HELPMODE_UNKNOWN, sizeof(Mode), Mode ) ;
  1939.   }
  1940.  
  1941.   WinLoadString ( Data->hAB, Data->Library, IDS_HELPSUBITEMNOTFOUND, sizeof(Format), Format ) ;
  1942.  
  1943.   sprintf ( Message, Format, Mode, Topic, Subtopic ) ;
  1944.  
  1945.  /***************************************************************************
  1946.   * Display the error message.                            *
  1947.   ***************************************************************************/
  1948.  
  1949.   WinMessageBox
  1950.   (
  1951.     HWND_DESKTOP,
  1952.     hwnd,
  1953.     Message,
  1954.     Title,
  1955.     0,
  1956.     MB_OK | MB_WARNING
  1957.   ) ;
  1958.  
  1959.  /***************************************************************************
  1960.   * Return zero, indicating that the message was processed.            *
  1961.   ***************************************************************************/
  1962.  
  1963.   return ( MRFROMSHORT ( 0 ) ) ;
  1964.  
  1965.   hwnd = hwnd ;  msg = msg ;  mp1 = mp1 ;  mp2 = mp2 ;
  1966. }
  1967.  
  1968. /****************************************************************************
  1969.  *                                        *
  1970.  *    Process Refresh message.                        *
  1971.  *                                        *
  1972.  ****************************************************************************/
  1973.  
  1974. static MRESULT APIENTRY Refresh
  1975.   HWND hwnd, 
  1976.   USHORT msg, 
  1977.   MPARAM mp1, 
  1978.   MPARAM mp2
  1979. )
  1980. {
  1981.  /***************************************************************************
  1982.   * Local Declarations                                *
  1983.   ***************************************************************************/
  1984.  
  1985.   PDATA Data ;
  1986.  
  1987.  /***************************************************************************
  1988.   * Find the instance data.                            *
  1989.   ***************************************************************************/
  1990.  
  1991.   Data = (PDATA) WinQueryWindowPtr ( hwnd, QWL_USER ) ;
  1992.  
  1993.  /***************************************************************************
  1994.   * Save the idle counter.                            *
  1995.   ***************************************************************************/
  1996.  
  1997.   Data->IdleCount = LONGFROMMP ( mp1 ) ;
  1998.  
  1999.  /***************************************************************************
  2000.   * Update the statistics.                            *
  2001.   ***************************************************************************/
  2002.  
  2003.   UpdateWindow ( hwnd, Data, FALSE ) ;
  2004.  
  2005.  /***************************************************************************
  2006.   * Return zero, indicating that the message was processed.            *
  2007.   ***************************************************************************/
  2008.  
  2009.   return ( MRFROMSHORT ( 0 ) ) ;
  2010.  
  2011.   hwnd = hwnd ;  msg = msg ;  mp1 = mp1 ;  mp2 = mp2 ;
  2012. }
  2013.  
  2014.  
  2015. /****************************************************************************
  2016.  *                                        *
  2017.  *                 Get Profile Data                    *
  2018.  *                                        *
  2019.  ****************************************************************************/
  2020.  
  2021. static void GetProfile ( HAB hAB, HMODULE Library, PROFILE *Profile )
  2022. {
  2023.  /***************************************************************************
  2024.   * Local Declarations                                *
  2025.   ***************************************************************************/
  2026.  
  2027.   #define ITEM_BASE_COUNT    6
  2028.   #define MAX_DRIVES        26
  2029.  
  2030.   static ITEM Items [ ITEM_BASE_COUNT + MAX_DRIVES ] =
  2031.   {
  2032.     {
  2033.       "ShowTime",      TRUE, "", 0L, "", IDM_SHOW_CLOCK,
  2034.       ComputeTime,     0, 0, ' '
  2035.     },
  2036.  
  2037.     {
  2038.       "ShowMemory",    TRUE, "", 0L, "", IDM_SHOW_MEMORY,
  2039.       ComputeFreeMemory, 0, 1024, 'K'
  2040.     },
  2041.  
  2042.     {
  2043.       "ShowSwapsize",  TRUE, "", 0L, "", IDM_SHOW_SWAPSIZE,
  2044.       ComputeSwapSize,     0, 1024, 'K'
  2045.     },
  2046.  
  2047.     {
  2048.       "ShowSwapfree",  TRUE, "", 0L, "", IDM_SHOW_SWAPFREE,
  2049.       ComputeSwapFree,     0, 1024, 'K'
  2050.     },
  2051.  
  2052.     {
  2053.       "ShowSpoolSize", TRUE, "", 0L, "", IDM_SHOW_SPOOLSIZE,
  2054.       ComputeSpoolSize,  0, 1024, 'K'
  2055.     },
  2056.  
  2057.     {
  2058.       "ShowCpuLoad",   TRUE, "", 0L, "", IDM_SHOW_CPULOAD,
  2059.       ComputeCpuLoad,     0, 0,      '%'
  2060.     }
  2061.   } ;
  2062.  
  2063.   int Count ;
  2064.   USHORT Drive ;
  2065.   ULONG Drives ;
  2066.   int i ;
  2067.   ULONG Size ;
  2068.  
  2069.   char LabelFormat [80] ;
  2070.   char OptionFormat [80] ;
  2071.  
  2072.  /***************************************************************************
  2073.   * Get fixed string information for item list.                 *
  2074.   ***************************************************************************/
  2075.  
  2076.   for ( i=0; i<ITEM_BASE_COUNT; i++ )
  2077.   {
  2078.     WinLoadString ( hAB, Library, i*2+IDS_SHOW_CLOCK_LABEL,
  2079.       sizeof(Items[i].Label), Items[i].Label ) ;
  2080.     WinLoadString ( hAB, Library, i*2+IDS_SHOW_CLOCK_OPTION,
  2081.       sizeof(Items[i].MenuOption), Items[i].MenuOption ) ;
  2082.   }
  2083.  
  2084.   WinLoadString ( hAB, Library, IDS_SHOW_DRIVE_FREE_LABEL, sizeof(LabelFormat), LabelFormat ) ;
  2085.   WinLoadString ( hAB, Library, IDS_SHOW_DRIVE_FREE_OPTION, sizeof(OptionFormat), OptionFormat ) ;
  2086.  
  2087.  /***************************************************************************
  2088.   * Add items for each drive on the system.                    *
  2089.   ***************************************************************************/
  2090.  
  2091.   Count = ITEM_BASE_COUNT ;
  2092.  
  2093.   DosQCurDisk ( &Drive, &Drives ) ;
  2094.  
  2095.   Drives >>= 2 ;
  2096.  
  2097.   for ( Drive=3; Drive<MAX_DRIVES; Drive++ )
  2098.   {
  2099.     if ( Drives & 1 )
  2100.     {
  2101.       USHORT Action ;
  2102.       BOOL Addit = FALSE ;
  2103.       USHORT Handle ;
  2104.       BYTE Path [3] ;
  2105.       USHORT Status ;
  2106.  
  2107.       Path[0] = (BYTE) ( Drive + 'A' - 1 ) ;
  2108.       Path[1] = ':' ;
  2109.       Path[2] = 0 ;
  2110.  
  2111.       Status = DosOpen ( Path, &Handle, &Action, 0, 0, FILE_OPEN,
  2112.     OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE |
  2113.     OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR, 0 ) ;
  2114.  
  2115.       if ( Status == 0 )
  2116.       {
  2117.     BIOSPARAMETERBLOCK BiosParms ;
  2118.     BYTE Command = 0 ;
  2119.  
  2120.     if ( !DosDevIOCtl ( &BiosParms, &Command, DSK_GETDEVICEPARAMS, IOCTL_DISK, Handle ) )
  2121.     {
  2122.       if ( BiosParms.fsDeviceAttr & 1 )  // Must be FIXED drive.
  2123.       {
  2124.         Addit = TRUE ;
  2125.       }
  2126.     }
  2127.     DosClose ( Handle ) ;
  2128.       }
  2129.       else if ( Status == ERROR_NETWORK_ACCESS_DENIED )
  2130.       {
  2131.     Addit = TRUE ;
  2132.       }
  2133.       else if ( Status == ERROR_INVALID_ACCESS )
  2134.       {
  2135.     Addit = TRUE ;
  2136.       }
  2137.       else
  2138.       {
  2139.         Debug ( HWND_DESKTOP, "Unable to open drive '%s'.  Status=%04X.",
  2140.           Path, Status ) ;
  2141.       }
  2142.  
  2143.       if ( Addit )
  2144.       {
  2145.     sprintf ( Items[Count].Name,       "ShowDrive%c:", Drive+'A'-1 ) ;
  2146.     sprintf ( Items[Count].Label,       LabelFormat,    Drive+'A'-1 ) ;
  2147.     sprintf ( Items[Count].MenuOption, OptionFormat,   Drive+'A'-1 ) ;
  2148.  
  2149.     Items[Count].MenuId = IDM_SHOW_DRIVE_FREE + Drive ;
  2150.     Items[Count].NewValue = ComputeDriveFree ;
  2151.     Items[Count].Parm = Drive ;
  2152.     Items[Count].Divisor = 1024 ;
  2153.     Items[Count].Suffix = 'K' ;
  2154.     Count ++ ;
  2155.       }
  2156.     }
  2157.     Drives >>= 1 ;
  2158.   }
  2159.  
  2160.  /***************************************************************************
  2161.   * Save pointer to fixed configuration information.                *
  2162.   ***************************************************************************/
  2163.  
  2164.   Profile->Items = Items ;
  2165.   Profile->ItemCount = Count ;
  2166.  
  2167.  /***************************************************************************
  2168.   * Get the window's current size and position.                             *
  2169.   ***************************************************************************/
  2170.  
  2171.   memset ( &Profile->Position, 0, sizeof(Profile->Position) ) ;
  2172.   Profile->fPosition = FALSE ;
  2173.   if
  2174.   (
  2175.     PrfQueryProfileSize ( HINI_PROFILE, PROGRAM_NAME, "Position", &Size )
  2176.     AND
  2177.     ( Size == sizeof(Profile->Position) )
  2178.     AND
  2179.     PrfQueryProfileData ( HINI_PROFILE, PROGRAM_NAME, "Position", &Profile->Position, &Size )
  2180.   )
  2181.   {
  2182.     Profile->fPosition = TRUE ;
  2183.   }
  2184.  
  2185.  /***************************************************************************
  2186.   * Get the program options.                            *
  2187.   ***************************************************************************/
  2188.  
  2189.   Profile->HideControls = FALSE ;
  2190.   if
  2191.   (
  2192.     PrfQueryProfileSize ( HINI_PROFILE, PROGRAM_NAME, "HideControls", &Size )
  2193.     AND
  2194.     ( Size == sizeof(Profile->HideControls) )
  2195.     AND
  2196.     PrfQueryProfileData ( HINI_PROFILE, PROGRAM_NAME, "HideControls", &Profile->HideControls, &Size )
  2197.   )
  2198.   {
  2199.     ;
  2200.   }
  2201.  
  2202.   Profile->TimerInterval = 1000 ;
  2203.   if
  2204.   (
  2205.     PrfQueryProfileSize ( HINI_PROFILE, PROGRAM_NAME, "TimerInterval", &Size )
  2206.     AND
  2207.     ( Size == sizeof(Profile->TimerInterval) )
  2208.     AND
  2209.     PrfQueryProfileData ( HINI_PROFILE, PROGRAM_NAME, "TimerInterval", &Profile->TimerInterval, &Size )
  2210.   )
  2211.   {
  2212.     ;
  2213.   }
  2214.  
  2215.  /***************************************************************************
  2216.   * Get the item options.                            *
  2217.   ***************************************************************************/
  2218.  
  2219.   for ( i=0; i<Profile->ItemCount; i++ )
  2220.   {
  2221.     PITEM Item = & Profile->Items [i] ;
  2222.  
  2223.     Item->Flag = TRUE ;
  2224.     if
  2225.     (
  2226.       PrfQueryProfileSize ( HINI_PROFILE, PROGRAM_NAME, Item->Name, &Size )
  2227.       AND
  2228.       ( Size == sizeof(Item->Flag) )
  2229.       AND
  2230.       PrfQueryProfileData ( HINI_PROFILE, PROGRAM_NAME, Item->Name, &Item->Flag, &Size )
  2231.     )
  2232.     {
  2233.       ;
  2234.     }
  2235.   }
  2236.  
  2237.  /***************************************************************************
  2238.   * Get the presentation parameters.                        *
  2239.   ***************************************************************************/
  2240.  
  2241.   strcpy ( Profile->FontNameSize, "" ) ;
  2242.   Profile->fFontNameSize = FALSE ;
  2243.   if
  2244.   (
  2245.     PrfQueryProfileSize ( HINI_PROFILE, PROGRAM_NAME, "FontNameSize", &Size )
  2246.     AND
  2247.     ( Size == sizeof(Profile->FontNameSize) )
  2248.     AND
  2249.     PrfQueryProfileData ( HINI_PROFILE, PROGRAM_NAME, "FontNameSize", &Profile->FontNameSize, &Size )
  2250.   )
  2251.   {
  2252.     Profile->fFontNameSize = TRUE ;
  2253.   }
  2254.  
  2255.   Profile->BackColor = WinQuerySysColor ( HWND_DESKTOP, SYSCLR_WINDOW, 0L ) ;
  2256.   Profile->fBackColor = FALSE ;
  2257.   if
  2258.   (
  2259.     PrfQueryProfileSize ( HINI_PROFILE, PROGRAM_NAME, "BackgroundColor", &Size )
  2260.     AND
  2261.     ( Size == sizeof(Profile->BackColor) )
  2262.     AND
  2263.     PrfQueryProfileData ( HINI_PROFILE, PROGRAM_NAME, "BackgroundColor", &Profile->BackColor, &Size )
  2264.   )
  2265.   {
  2266.     Profile->fBackColor = TRUE ;
  2267.   }
  2268.  
  2269.   Profile->TextColor = WinQuerySysColor ( HWND_DESKTOP, SYSCLR_OUTPUTTEXT, 0L ) ;
  2270.   Profile->fTextColor = FALSE ;
  2271.   if
  2272.   (
  2273.     PrfQueryProfileSize ( HINI_PROFILE, PROGRAM_NAME, "ForegroundColor", &Size )
  2274.     AND
  2275.     ( Size == sizeof(Profile->TextColor) )
  2276.     AND
  2277.     PrfQueryProfileData ( HINI_PROFILE, PROGRAM_NAME, "ForegroundColor", &Profile->TextColor, &Size )
  2278.   )
  2279.   {
  2280.     Profile->fTextColor = TRUE ;
  2281.   }
  2282. }
  2283.  
  2284. /****************************************************************************
  2285.  *                                        *
  2286.  *                 Put Profile Data                    *
  2287.  *                                        *
  2288.  ****************************************************************************/
  2289.  
  2290. static void PutProfile ( PROFILE *Profile )
  2291. {
  2292.  /***************************************************************************
  2293.   * Local Declarations                                *
  2294.   ***************************************************************************/
  2295.  
  2296.   int i ;
  2297.  
  2298.  /***************************************************************************
  2299.   * Save the window's current size and position.                            *
  2300.   ***************************************************************************/
  2301.  
  2302.   PrfWriteProfileData
  2303.   (
  2304.     HINI_USERPROFILE,
  2305.     PROGRAM_NAME,
  2306.     "Position",
  2307.     &Profile->Position,
  2308.     (ULONG)sizeof(Profile->Position)
  2309.   ) ;
  2310.  
  2311.  /***************************************************************************
  2312.   * Save the program options.                            *
  2313.   ***************************************************************************/
  2314.  
  2315.   PrfWriteProfileData
  2316.   (
  2317.     HINI_USERPROFILE,
  2318.     PROGRAM_NAME,
  2319.     "HideControls",
  2320.     &Profile->HideControls,
  2321.     (ULONG)sizeof(Profile->HideControls)
  2322.   ) ;
  2323.  
  2324.   PrfWriteProfileData
  2325.   (
  2326.     HINI_USERPROFILE,
  2327.     PROGRAM_NAME,
  2328.     "TimerInterval",
  2329.     &Profile->TimerInterval,
  2330.     (ULONG)sizeof(Profile->TimerInterval)
  2331.   ) ;
  2332.  
  2333.  /***************************************************************************
  2334.   * Save the item options.                            *
  2335.   ***************************************************************************/
  2336.  
  2337.   for ( i=0; i<Profile->ItemCount; i++ )
  2338.   {
  2339.     PITEM Item = & Profile->Items [i] ;
  2340.  
  2341.     PrfWriteProfileData
  2342.     (
  2343.       HINI_USERPROFILE,
  2344.       PROGRAM_NAME,
  2345.       Item->Name,
  2346.       &Item->Flag,
  2347.       (ULONG)sizeof(Item->Flag)
  2348.     ) ;
  2349.   }
  2350.  
  2351.  /***************************************************************************
  2352.   * Save the presentation parameters.                        *
  2353.   ***************************************************************************/
  2354.  
  2355.   if ( Profile->fFontNameSize )
  2356.   {
  2357.     PrfWriteProfileData
  2358.     (
  2359.       HINI_USERPROFILE,
  2360.       PROGRAM_NAME,
  2361.       "FontNameSize",
  2362.       Profile->FontNameSize,
  2363.       (ULONG)sizeof(Profile->FontNameSize)
  2364.     ) ;
  2365.   }
  2366.  
  2367.   if ( Profile->fBackColor )
  2368.   {
  2369.     PrfWriteProfileData
  2370.     (
  2371.       HINI_USERPROFILE,
  2372.       PROGRAM_NAME,
  2373.       "BackgroundColor",
  2374.       &Profile->BackColor,
  2375.       (ULONG)sizeof(Profile->BackColor)
  2376.     ) ;
  2377.   }
  2378.  
  2379.   if ( Profile->fTextColor )
  2380.   {
  2381.     PrfWriteProfileData
  2382.     (
  2383.       HINI_USERPROFILE,
  2384.       PROGRAM_NAME,
  2385.       "ForegroundColor",
  2386.       &Profile->TextColor,
  2387.       (ULONG)sizeof(Profile->TextColor)
  2388.     ) ;
  2389.   }
  2390. }
  2391.  
  2392. /****************************************************************************
  2393.  *                                        *
  2394.  *    Scan CONFIG.SYS for a keyword.    Return the value.            *
  2395.  *                                        *
  2396.  ****************************************************************************/
  2397.  
  2398. static PCHAR ScanSystemConfig ( PCHAR Keyword )
  2399. {
  2400.  /***************************************************************************
  2401.   * Local Declarations                                *
  2402.   ***************************************************************************/
  2403.  
  2404.   static char Buffer [500] ;
  2405.   FILE *File ;
  2406.   SEL GlobalSelector ;
  2407.   SEL LocalSelector ;
  2408.   char Path [_MAX_PATH] ;
  2409.   GINFOSEG FAR *pGlobalInfoSeg ;
  2410.  
  2411.  /***************************************************************************
  2412.   * Get the boot drive number from the global information segment.        *
  2413.   ***************************************************************************/
  2414.  
  2415.   DosGetInfoSeg ( &GlobalSelector, &LocalSelector ) ;
  2416.  
  2417.   pGlobalInfoSeg = MAKEPGINFOSEG ( GlobalSelector ) ;
  2418.  
  2419.  /***************************************************************************
  2420.   * Build the CONFIG.SYS path.                            *
  2421.   ***************************************************************************/
  2422.  
  2423.   Path[0] = (char) ( pGlobalInfoSeg->bootdrive + 'A' - 1 ) ;
  2424.   Path[1] = 0 ;
  2425.   strcat ( Path, ":\\CONFIG.SYS" ) ;
  2426.  
  2427.  /***************************************************************************
  2428.   * Open CONFIG.SYS for reading.                        *
  2429.   ***************************************************************************/
  2430.  
  2431.   File = fopen ( Path, "rt" ) ;
  2432.   if ( NOT File )
  2433.   {
  2434.     return ( NULL ) ;
  2435.   }
  2436.  
  2437.  /***************************************************************************
  2438.   * While there're more lines in CONFIG.SYS, read a line and check it.      *
  2439.   ***************************************************************************/
  2440.  
  2441.   while ( fgets ( Buffer, sizeof(Buffer), File ) )
  2442.   {
  2443.  
  2444.    /*************************************************************************
  2445.     * Clean any trailing newline character from the input string.        *
  2446.     *************************************************************************/
  2447.  
  2448.     if ( Buffer[strlen(Buffer)-1] == '\n' )
  2449.     {
  2450.       Buffer[strlen(Buffer)-1] = 0 ;
  2451.     }
  2452.  
  2453.    /*************************************************************************
  2454.     * If keyword starts the line, we've found the line we want.  Close      *
  2455.     *    the file and return a pointer to the parameter text.            *
  2456.     *************************************************************************/
  2457.  
  2458.     if ( NOT strnicmp ( Buffer, Keyword, strlen(Keyword) )
  2459.       AND ( Buffer[strlen(Keyword)] == '=' ) )
  2460.     {
  2461.       fclose ( File ) ;
  2462.       return ( Buffer + strlen(Keyword) + 1 ) ;
  2463.     }
  2464.   }
  2465.  
  2466.  /***************************************************************************
  2467.   * Close the file.  We haven't found the line we wanted.                   *
  2468.   ***************************************************************************/
  2469.  
  2470.   fclose ( File ) ;
  2471.  
  2472.   return ( NULL ) ;
  2473. }
  2474.  
  2475. /****************************************************************************
  2476.  *                                        *
  2477.  *             Resize Client Window                    *
  2478.  *                                        *
  2479.  ****************************************************************************/
  2480.  
  2481. static void ResizeWindow ( HWND hwnd, PROFILE *Profile )
  2482. {
  2483.  /***************************************************************************
  2484.   * Local Declarations                                *
  2485.   ***************************************************************************/
  2486.  
  2487.   SHORT Count ;
  2488.   SHORT fHadToHide = FALSE ;
  2489.   SHORT fHadToRestore = FALSE ;
  2490.   LONG Height ;
  2491.   HPS hPS ;
  2492.   HWND hwndFrame ;
  2493.   short i ;
  2494.   RECTL Rectangle ;
  2495.   char Text [100] ;
  2496.   LONG Widest ;
  2497.  
  2498.  /***************************************************************************
  2499.   * If the window is visible and minimized, restore it invisibly.        *
  2500.   ***************************************************************************/
  2501.  
  2502.   hwndFrame = WinQueryWindow ( hwnd, QW_PARENT, FALSE ) ;
  2503.  
  2504.   if ( Profile->Position.fs & SWP_MINIMIZE )
  2505.   {
  2506.     if ( WinIsWindowVisible ( hwndFrame ) )
  2507.     {
  2508.       WinShowWindow ( hwndFrame, FALSE ) ;
  2509.       fHadToHide = TRUE ;
  2510.     }
  2511.     WinSetWindowPos ( hwndFrame, NULL, 0, 0, 0, 0, SWP_RESTORE ) ;
  2512.     fHadToRestore = TRUE ;
  2513.   }
  2514.  
  2515.  /***************************************************************************
  2516.   * Determine how many items are to be displayed.                *
  2517.   ***************************************************************************/
  2518.  
  2519.   hPS = WinGetPS ( hwnd ) ;
  2520.  
  2521.   Count = 0 ;
  2522.   Widest = 0 ;
  2523.   Height = 0 ;
  2524.  
  2525.   for ( i=0; i<Profile->ItemCount; i++ )
  2526.   {
  2527.     PITEM Item = & Profile->Items [i] ;
  2528.  
  2529.     if ( Item->Flag )
  2530.     {
  2531.       Count ++ ;
  2532.  
  2533.       sprintf ( Text, "%s 1,234,567K", Item->Label ) ;
  2534.  
  2535.       WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  2536.  
  2537.       WinDrawText ( hPS, strlen(Text), Text,
  2538.     &Rectangle, 0L, 0L, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  2539.  
  2540.       Widest = max ( Widest, (Rectangle.xRight-Rectangle.xLeft+1) ) ;
  2541.  
  2542.       Height += Rectangle.yTop - Rectangle.yBottom ;
  2543.     }
  2544.   }
  2545.  
  2546.   WinReleasePS ( hPS ) ;
  2547.  
  2548.  /***************************************************************************
  2549.   * Get the window's current size & position.                               *
  2550.   ***************************************************************************/
  2551.  
  2552.   WinQueryWindowRect ( hwndFrame, &Rectangle ) ;
  2553.  
  2554.   WinCalcFrameRect ( hwndFrame, &Rectangle, TRUE ) ;
  2555.  
  2556.  /***************************************************************************
  2557.   * Adjust the window's width & height.                                     *
  2558.   ***************************************************************************/
  2559.  
  2560.   Rectangle.xRight  = Rectangle.xLeft + Widest ;
  2561.  
  2562.   Rectangle.yTop    = Rectangle.yBottom + Height ;
  2563.  
  2564.  /***************************************************************************
  2565.   * Compute new frame size and apply it.                    *
  2566.   ***************************************************************************/
  2567.  
  2568.   WinCalcFrameRect ( hwndFrame, &Rectangle, FALSE ) ;
  2569.  
  2570.   WinSetWindowPos ( hwndFrame, NULL, 0, 0,
  2571.     (SHORT) (Rectangle.xRight-Rectangle.xLeft),
  2572.     (SHORT) (Rectangle.yTop-Rectangle.yBottom),
  2573.     SWP_SIZE ) ;
  2574.  
  2575.  /***************************************************************************
  2576.   * Return the window to its original state.                    *
  2577.   ***************************************************************************/
  2578.  
  2579.   if ( fHadToRestore )
  2580.   {
  2581.     WinSetWindowPos ( hwndFrame, NULL,
  2582.       Profile->Position.x, Profile->Position.y,
  2583.       Profile->Position.cx, Profile->Position.cy,
  2584.       SWP_MOVE | SWP_SIZE | SWP_MINIMIZE ) ;
  2585.   }
  2586.  
  2587.   if ( fHadToHide )
  2588.   {
  2589.     WinShowWindow ( hwndFrame, TRUE ) ;
  2590.   }
  2591.  
  2592.  /***************************************************************************
  2593.   * Invalidate the window so that it gets repainted.                *
  2594.   ***************************************************************************/
  2595.  
  2596.   WinInvalidateRect ( hwnd, NULL, TRUE ) ;
  2597. }
  2598.  
  2599. /****************************************************************************
  2600.  *                                        *
  2601.  *            Hide Window Controls                    *
  2602.  *                                        *
  2603.  ****************************************************************************/
  2604.  
  2605. static void HideControls
  2606. (
  2607.   BOOL fHide,
  2608.   HWND hwndFrame,
  2609.   HWND hwndSysMenu,
  2610.   HWND hwndTitleBar,
  2611.   HWND hwndMinMax
  2612. )
  2613. {
  2614.  /***************************************************************************
  2615.   * Local Declarations                                *
  2616.   ***************************************************************************/
  2617.  
  2618.   SWP Position ;
  2619.   RECTL Rectangle ;
  2620.  
  2621.  /***************************************************************************
  2622.   * Determine client window and location.                    *
  2623.   ***************************************************************************/
  2624.  
  2625.   WinQueryWindowPos ( hwndFrame, &Position ) ;
  2626.  
  2627.   Rectangle.xLeft   = Position.x ;
  2628.   Rectangle.xRight  = Position.x + Position.cx ;
  2629.   Rectangle.yBottom = Position.y ;
  2630.   Rectangle.yTop    = Position.y + Position.cy ;
  2631.  
  2632.   WinCalcFrameRect ( hwndFrame, &Rectangle, TRUE ) ;
  2633.  
  2634.  /***************************************************************************
  2635.   * Hide or reveal the controls windows by changing their parentage.        *
  2636.   ***************************************************************************/
  2637.  
  2638.   if ( fHide )
  2639.   {
  2640.     WinSetParent ( hwndSysMenu,  HWND_OBJECT, FALSE ) ;
  2641.     WinSetParent ( hwndTitleBar, HWND_OBJECT, FALSE ) ;
  2642.     WinSetParent ( hwndMinMax,     HWND_OBJECT, FALSE ) ;
  2643.   }
  2644.   else
  2645.   {
  2646.     WinSetParent ( hwndSysMenu,  hwndFrame, TRUE ) ;
  2647.     WinSetParent ( hwndTitleBar, hwndFrame, TRUE ) ;
  2648.     WinSetParent ( hwndMinMax,     hwndFrame, TRUE ) ;
  2649.   }
  2650.  
  2651.  /***************************************************************************
  2652.   * Tell the frame that things have changed.  Let it update the window.     *
  2653.   ***************************************************************************/
  2654.  
  2655.   WinSendMsg ( hwndFrame, WM_UPDATEFRAME,
  2656.     MPFROMSHORT ( FCF_TITLEBAR | FCF_SYSMENU | FCF_MINBUTTON ), 0L ) ;
  2657.  
  2658.  /***************************************************************************
  2659.   * Reposition the frame around the client window, which is left be.        *
  2660.   ***************************************************************************/
  2661.  
  2662.   WinCalcFrameRect ( hwndFrame, &Rectangle, FALSE ) ;
  2663.  
  2664.   WinSetWindowPos ( hwndFrame, NULL,
  2665.     (SHORT) Rectangle.xLeft,  (SHORT) Rectangle.yBottom,
  2666.     (SHORT) (Rectangle.xRight-Rectangle.xLeft),
  2667.     (SHORT) (Rectangle.yTop-Rectangle.yBottom),
  2668.     SWP_SIZE | SWP_MOVE ) ;
  2669. }
  2670.  
  2671. /****************************************************************************
  2672.  *                                        *
  2673.  *    Update Window                                *
  2674.  *                                        *
  2675.  ****************************************************************************/
  2676.  
  2677. #pragma optimize ( "gle", off )
  2678.  
  2679. static void UpdateWindow ( HWND hwnd, PDATA Data, BOOL All )
  2680. {
  2681.  /***************************************************************************
  2682.   *                Declarations                    *
  2683.   ***************************************************************************/
  2684.  
  2685.   int Count ;
  2686.   HPS hPS ;
  2687.   short i ;
  2688.   RECTL Rectangle ;
  2689.   char Text [100] ;
  2690.  
  2691.  /***************************************************************************
  2692.   * Determine how many items are to be displayed.                *
  2693.   ***************************************************************************/
  2694.  
  2695.   Count = 0 ;
  2696.   for ( i=0; i<Data->Profile.ItemCount; i++ )
  2697.   {
  2698.     if ( Data->Profile.Items[i].Flag )
  2699.     {
  2700.       Count ++ ;
  2701.     }
  2702.   }
  2703.  
  2704.  /***************************************************************************
  2705.   * Get presentation space and make it use RGB colors.                *
  2706.   ***************************************************************************/
  2707.  
  2708.   hPS = WinGetPS ( hwnd ) ;
  2709.   GpiCreateLogColorTable ( hPS, LCOL_RESET, LCOLF_RGB, 0L, 0L, NULL ) ;
  2710.  
  2711.  /***************************************************************************
  2712.   * Get the window's size and determine the initial position.               *
  2713.   ***************************************************************************/
  2714.  
  2715.   WinQueryWindowRect ( hwnd, &Rectangle ) ;
  2716.  
  2717.   Rectangle.xLeft += Data->Width / 2 ;
  2718.   Rectangle.xRight -= Data->Width / 2 ;
  2719.  
  2720.   Rectangle.yBottom = Data->Height * ( Count - 1 ) ;
  2721.   Rectangle.yTop = Rectangle.yBottom + Data->Height ;
  2722.  
  2723.  /***************************************************************************
  2724.   * Review all items.  Display those changed, or all.                *
  2725.   ***************************************************************************/
  2726.  
  2727.   for ( i=0; i<Data->Profile.ItemCount; i++ )
  2728.   {
  2729.     PITEM Item = & Data->Profile.Items [i] ;
  2730.     ULONG NewValue ;
  2731.  
  2732.     if ( Item->Flag )
  2733.     {
  2734.       NewValue = Item->NewValue ( Data, Item->Parm ) ;
  2735.  
  2736.       if ( All OR ( NewValue != Item->Value ) )
  2737.       {
  2738.     switch ( i )
  2739.     {
  2740.       case ITEM_CLOCK:
  2741.       {
  2742.         ULONG Month  = ( NewValue % 100000000L ) / 1000000L ;
  2743.         ULONG Day     = ( NewValue % 1000000L ) / 10000L ;
  2744.         ULONG Hour     = ( NewValue % 10000L ) / 100L ;
  2745.         ULONG Minute = ( NewValue % 100L ) ;
  2746.  
  2747.         switch ( Data->CountryInfo.fsDateFmt )
  2748.         {
  2749.           case DATEFMT_DD_MM_YY:
  2750.         sprintf ( Text, "%02lu%s%02lu ",
  2751.           Day, Data->CountryInfo.szDateSeparator, Month ) ;
  2752.         break ;
  2753.  
  2754.           case DATEFMT_YY_MM_DD:
  2755.           case DATEFMT_MM_DD_YY:
  2756.           default:
  2757.         sprintf ( Text, "%02lu%s%02lu ",
  2758.           Month, Data->CountryInfo.szDateSeparator, Day ) ;
  2759.         break ;
  2760.         }
  2761.  
  2762.         if ( Data->CountryInfo.fsTimeFmt )
  2763.         {
  2764.           sprintf ( Text+strlen(Text), "%02lu%s%02lu",
  2765.         Hour,
  2766.         Data->CountryInfo.szTimeSeparator,
  2767.         Minute ) ;
  2768.         }
  2769.         else
  2770.         {
  2771.           PCHAR AmPm ;
  2772.  
  2773.           if ( Hour )
  2774.           {
  2775.         if ( Hour < 12 )
  2776.         {
  2777.           AmPm = "a" ;
  2778.         }
  2779.         else if ( Hour == 12 )
  2780.         {
  2781.           if ( Minute )
  2782.             AmPm = "p" ;
  2783.           else
  2784.             AmPm = "a" ;
  2785.         }
  2786.         else if ( Hour > 12 )
  2787.         {
  2788.           Hour -= 12 ;
  2789.           AmPm = "p" ;
  2790.         }
  2791.           }
  2792.           else
  2793.           {
  2794.         Hour = 12 ;
  2795.         if ( Minute )
  2796.           AmPm = "a" ;
  2797.         else
  2798.           AmPm = "p" ;
  2799.           }
  2800.           sprintf ( Text+strlen(Text), "%02lu%s%02lu%s",
  2801.         Hour, Data->CountryInfo.szTimeSeparator, Minute, AmPm ) ;
  2802.         }
  2803.         break ;
  2804.       }
  2805.  
  2806.       default:
  2807.       {
  2808.         memset ( Text, 0, sizeof(Text) ) ;
  2809.  
  2810.         if ( Item->Divisor )
  2811.         {
  2812.           if ( NewValue < Item->Divisor * 1000 )
  2813.         sprintf ( Text, "%lu", NewValue ) ;
  2814.           else
  2815.         sprintf ( Text, "%lu", (NewValue+Item->Divisor/2)/Item->Divisor ) ;
  2816.         }
  2817.         else
  2818.         {
  2819.           sprintf ( Text, "%lu", NewValue ) ;
  2820.         }
  2821.  
  2822.         {
  2823.           PCHAR p1, p2 ;
  2824.           CHAR Work[100] ;
  2825.  
  2826.           p1 = Text ;
  2827.           p2 = Work ;
  2828.           while ( *p1 )
  2829.           {
  2830.         *p2 = *p1 ;
  2831.         p1 ++ ;
  2832.         p2 ++ ;
  2833.         if ( *p1 )
  2834.         {
  2835.           if ( strlen(p1) % 3 == 0 )
  2836.           {
  2837.             *p2 = Data->CountryInfo.szThousandsSeparator [0] ;
  2838.             p2 ++ ;
  2839.           }
  2840.         }
  2841.           }
  2842.           *p2 = 0 ;
  2843.           strcpy ( Text, Work ) ;
  2844.         }
  2845.  
  2846.         if ( Item->Divisor )
  2847.         {
  2848.           if ( NewValue < Item->Divisor * 1000 )
  2849.         Text[strlen(Text)] = ' ' ;
  2850.           else
  2851.         Text[strlen(Text)] = Item->Suffix ;
  2852.         }
  2853.         else
  2854.         {
  2855.           Text[strlen(Text)] = Item->Suffix ;
  2856.         }
  2857.       }
  2858.     }
  2859.  
  2860.     WinDrawText ( hPS, strlen(Text), Text, &Rectangle,
  2861.       Data->Profile.TextColor, Data->Profile.BackColor,
  2862.       DT_RIGHT | DT_BOTTOM | DT_ERASERECT ) ;
  2863.  
  2864.     strcpy ( Text, Item->Label ) ;
  2865.  
  2866.     WinDrawText ( hPS, strlen(Text), Text, &Rectangle,
  2867.       Data->Profile.TextColor, Data->Profile.BackColor,
  2868.       DT_LEFT | DT_BOTTOM ) ;
  2869.  
  2870.     Item->Value = NewValue ;
  2871.       }
  2872.       Rectangle.yBottom -= Data->Height ;
  2873.       Rectangle.yTop    -= Data->Height ;
  2874.     }
  2875.   }
  2876.  
  2877.  /***************************************************************************
  2878.   * Release the presentation space and return.                    *
  2879.   ***************************************************************************/
  2880.  
  2881.   WinReleasePS ( hPS ) ;
  2882. }
  2883.  
  2884. #pragma optimize ( "gle", on )
  2885.  
  2886.  
  2887. /****************************************************************************
  2888.  *                                        *
  2889.  *    Compute Time                                *
  2890.  *                                        *
  2891.  ****************************************************************************/
  2892.  
  2893. static ULONG ComputeTime ( PDATA Data, USHORT Dummy )
  2894. {
  2895.   char DateString [9] ;
  2896.   short Hour, Minute ;
  2897.   short Month, Day ;
  2898.   ULONG Time ;
  2899.   char TimeString [9] ;
  2900.  
  2901.   _strdate ( DateString ) ;
  2902.   _strtime ( TimeString ) ;
  2903.  
  2904.   Hour     = atoi ( TimeString + 0 ) ;
  2905.   Minute = atoi ( TimeString + 3 ) ;
  2906.  
  2907.   Month  = atoi ( DateString + 0 ) ;
  2908.   Day     = atoi ( DateString + 3 ) ;
  2909.  
  2910.   Time = Month ;
  2911.   Time *= 100 ;
  2912.   Time += Day ;
  2913.   Time *= 100 ;
  2914.   Time += Hour ;
  2915.   Time *= 100 ;
  2916.   Time += Minute ;
  2917.  
  2918.   return ( Time ) ;
  2919. }
  2920.  
  2921. /****************************************************************************
  2922.  *                                        *
  2923.  *    Compute Available Memory                            *
  2924.  *                                        *
  2925.  ****************************************************************************/
  2926.  
  2927. static ULONG ComputeFreeMemory ( PDATA Data, USHORT Dummy )
  2928. {
  2929.   ULONG MemFree ;
  2930.  
  2931.   DosMemAvail ( &MemFree ) ;
  2932.  
  2933.   return ( MemFree ) ;
  2934. }
  2935.  
  2936. /****************************************************************************
  2937.  *                                        *
  2938.  *    Compute Swap-File Size                            *
  2939.  *                                        *
  2940.  ****************************************************************************/
  2941.  
  2942. static ULONG ComputeSwapSize ( PDATA Data, USHORT Dummy )
  2943. {
  2944.  /***************************************************************************
  2945.   *                Declarations                    *
  2946.   ***************************************************************************/
  2947.  
  2948.   char Path [_MAX_PATH+1] ;
  2949.   struct stat Status ;
  2950.   ULONG SwapSize ;
  2951.  
  2952.  /***************************************************************************
  2953.   * Find the swap file and find its size.                    *
  2954.   ***************************************************************************/
  2955.  
  2956.   strcpy ( Path, Data->SwapPath ) ;
  2957.  
  2958.   if ( Path[strlen(Path)-1] != '\\' )
  2959.   {
  2960.     strcat ( Path, "\\" ) ;
  2961.   }
  2962.  
  2963.   strcat ( Path, "SWAPPER.DAT" ) ;
  2964.  
  2965.   SwapSize = 0 ;
  2966.   if ( stat ( Path, &Status ) == 0 )
  2967.   {
  2968.     SwapSize = Status.st_size ;
  2969.   }
  2970.  
  2971.   return ( SwapSize ) ;
  2972. }
  2973.  
  2974. /****************************************************************************
  2975.  *                                        *
  2976.  *    Compute Available Swap Space                        *
  2977.  *                                        *
  2978.  ****************************************************************************/
  2979.  
  2980. static ULONG ComputeSwapFree ( PDATA Data, USHORT Dummy )
  2981. {
  2982.  /***************************************************************************
  2983.   *                Declarations                    *
  2984.   ***************************************************************************/
  2985.  
  2986.   FSALLOCATE Allocation ;
  2987.   char Path [_MAX_PATH+1] ;
  2988.   ULONG SwapFree ;
  2989.  
  2990.  /***************************************************************************
  2991.   * Find the swap file and find its size.                    *
  2992.   ***************************************************************************/
  2993.  
  2994.   strcpy ( Path, Data->SwapPath ) ;
  2995.   strcat ( Path, "\\SWAPPER.DAT" ) ;
  2996.  
  2997.  /***************************************************************************
  2998.   * Compute swap device free space.                        *
  2999.   ***************************************************************************/
  3000.  
  3001.   SwapFree = 0 ;
  3002.   if ( Path[0] )
  3003.   {
  3004.     DosQFSInfo ( Path[0]-'A'+1, FSIL_ALLOC,
  3005.       (PBYTE)&Allocation, sizeof(Allocation) ) ;
  3006.  
  3007.     SwapFree = Allocation.cUnitAvail*Allocation.cSectorUnit*Allocation.cbSector ;
  3008.   }
  3009.  
  3010.  /***************************************************************************
  3011.   * Return swap device's free space, less the minimum free space.           *
  3012.   ***************************************************************************/
  3013.  
  3014.   if ( SwapFree < (ULONG)Data->MinFree*1024L )
  3015.     return ( 0L ) ;
  3016.   else
  3017.     return ( SwapFree - (ULONG)Data->MinFree * 1024L ) ;
  3018. }
  3019.  
  3020. /****************************************************************************
  3021.  *                                        *
  3022.  *    Compute Spool-file Size                            *
  3023.  *                                        *
  3024.  ****************************************************************************/
  3025.  
  3026. static ULONG ComputeSpoolSize ( PDATA Data, USHORT Dummy )
  3027. {
  3028.   USHORT Count ;
  3029.   FILEFINDBUF *Found ;
  3030.   HDIR hDir = HDIR_CREATE ;
  3031.   BYTE *Path ;
  3032.   USHORT PathSize ;
  3033.   ULONG TotalSize = 0 ;
  3034.  
  3035.   DosQSysInfo ( 0, (PBYTE)&PathSize, sizeof(PathSize) ) ;
  3036.  
  3037.   Path = malloc ( PathSize ) ;
  3038.   if ( Path == NULL )
  3039.   {
  3040.     return ( 0 ) ;
  3041.   }
  3042.  
  3043.   Found = malloc ( PathSize + sizeof(FILEFINDBUF) ) ;
  3044.   if ( Found == NULL )
  3045.   {
  3046.     free ( Path ) ;
  3047.     return ( 0 ) ;
  3048.   }
  3049.  
  3050.   strcpy ( Path, Data->SpoolPath ) ;
  3051.   strcat ( Path, "\\*.*" ) ;
  3052.  
  3053.   Count = 1 ;
  3054.   if ( !DosFindFirst2 ( Path, &hDir,
  3055.     FILE_NORMAL | FILE_READONLY | FILE_DIRECTORY | FILE_ARCHIVED,
  3056.     Found, PathSize+sizeof(FILEFINDBUF), &Count, FIL_STANDARD, 0L ) )
  3057.   {
  3058.     do
  3059.     {
  3060.       if ( !strcmp ( Found->achName, "." )
  3061.     OR !strcmp ( Found->achName, ".." ) )
  3062.       {
  3063.     continue ;
  3064.       }
  3065.  
  3066.       if ( Found->attrFile & FILE_DIRECTORY )
  3067.       {
  3068.     HDIR hDir = HDIR_CREATE ;
  3069.  
  3070.     strcpy ( Path, Data->SpoolPath ) ;
  3071.     strcat ( Path, "\\" ) ;
  3072.     strcat ( Path, Found->achName ) ;
  3073.     strcat ( Path, "\\*.*" ) ;
  3074.  
  3075.     Count = 1 ;
  3076.     if ( !DosFindFirst2 ( Path, &hDir,
  3077.       FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED,
  3078.       Found, PathSize+sizeof(FILEFINDBUF), &Count, FIL_STANDARD, 0L ) )
  3079.     {
  3080.       do
  3081.       {
  3082.         TotalSize += Found->cbFileAlloc ;
  3083.       }
  3084.       while ( !DosFindNext ( hDir, Found, PathSize+sizeof(FILEFINDBUF), &Count ) ) ;
  3085.       DosFindClose ( hDir ) ;
  3086.     }
  3087.     Count = 1 ;
  3088.       }
  3089.       else
  3090.       {
  3091.     TotalSize += Found->cbFileAlloc ;
  3092.       }
  3093.     }
  3094.     while ( !DosFindNext ( hDir, Found, PathSize+sizeof(FILEFINDBUF), &Count ) ) ;
  3095.     DosFindClose ( hDir ) ;
  3096.   }
  3097.  
  3098.   free ( Path ) ;
  3099.   free ( Found ) ;
  3100.  
  3101.   return ( TotalSize ) ;
  3102. }
  3103.  
  3104. /****************************************************************************
  3105.  *                                        *
  3106.  *    Compute CPU Load                                *
  3107.  *                                        *
  3108.  ****************************************************************************/
  3109.  
  3110. static ULONG ComputeCpuLoad ( PDATA Data, USHORT Dummy )
  3111. {
  3112.   static ULONG Max = 1 ;
  3113.  
  3114.   Max = (ULONG) max ( Max, Data->IdleCount ) ;
  3115.  
  3116.   return ( ( ( Max - Data->IdleCount ) * 100 ) / Max ) ;
  3117. }
  3118.  
  3119. /****************************************************************************
  3120.  *                                        *
  3121.  *    Compute Drive Free Space                            *
  3122.  *                                        *
  3123.  ****************************************************************************/
  3124.  
  3125. static ULONG ComputeDriveFree ( PDATA Data, USHORT Drive )
  3126. {
  3127.   FSALLOCATE Allocation ;
  3128.  
  3129.   DosQFSInfo ( Drive, FSIL_ALLOC,
  3130.     (PBYTE)&Allocation, sizeof(Allocation) ) ;
  3131.  
  3132.   return ( Allocation.cUnitAvail*Allocation.cSectorUnit*Allocation.cbSector ) ;
  3133. }
  3134.  
  3135. /****************************************************************************
  3136.  *                                        *
  3137.  *    Idle Counter Thread                            *
  3138.  *                                        *
  3139.  ****************************************************************************/
  3140.  
  3141. static void _far _cdecl IdleLoopThread ( PIDLE_PARMS Parms )
  3142. {
  3143.  /***************************************************************************
  3144.   * Set this thread's priority as low as it can go.                         *
  3145.   ***************************************************************************/
  3146.  
  3147.   DosSetPrty ( PRTYS_THREAD, PRTYC_IDLETIME, PRTYD_MINIMUM, 0 ) ;
  3148.  
  3149.  /***************************************************************************
  3150.   * Count until terminated.                            *
  3151.   ***************************************************************************/
  3152.  
  3153.   while ( 1 )
  3154.   {
  3155.     (*Parms->Counter) ++ ;
  3156.   }
  3157. }
  3158.  
  3159. /****************************************************************************
  3160.  *                                        *
  3161.  *    Monitor Loop Thread                            *
  3162.  *                                        *
  3163.  ****************************************************************************/
  3164.  
  3165. static void _far _cdecl MonitorLoopThread ( PMONITOR_PARMS Parms )
  3166. {
  3167.  /***************************************************************************
  3168.   * Local Declarations                                *
  3169.   ***************************************************************************/
  3170.  
  3171.  
  3172.   ULONG     CurrentCount ;
  3173.   ULONG     CurrentMilliseconds ;
  3174.   ULONG     DeltaMilliseconds ;
  3175.   ULONG     LastCounter = 0L ;
  3176.   ULONG     LastMilliseconds = 0L ;
  3177.   PGINFOSEG pGlobalInfoSeg = NULL ;
  3178.   PLINFOSEG pLocalInfoSeg = NULL ;
  3179.  
  3180.  /***************************************************************************
  3181.   * Set this thread's priority as high as it can go.                        *
  3182.   ***************************************************************************/
  3183.  
  3184.   DosSetPrty ( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, 0 ) ;
  3185.  
  3186.  /***************************************************************************
  3187.   * Get pointer to global information segment, where the time is kept.        *
  3188.   ***************************************************************************/
  3189.  
  3190.   DosGetInfoSeg ( &SELECTOROF(pGlobalInfoSeg), &SELECTOROF(pLocalInfoSeg) ) ;
  3191.  
  3192.  /***************************************************************************
  3193.   * Reset the last time seen.                            *
  3194.   ***************************************************************************/
  3195.  
  3196.   LastMilliseconds = pGlobalInfoSeg->msecs ;
  3197.  
  3198.  /***************************************************************************
  3199.   * Loop forever . . .                                *
  3200.   ***************************************************************************/
  3201.  
  3202.   while ( 1 )
  3203.   {
  3204.    /*************************************************************************
  3205.     * Sleep for a bit.                                *
  3206.     *************************************************************************/
  3207.  
  3208.     DosSleep ( *Parms->Interval ) ;
  3209.  
  3210.    /*************************************************************************
  3211.     * Find out how much time went by.                        *
  3212.     *************************************************************************/
  3213.  
  3214.     CurrentMilliseconds = pGlobalInfoSeg->msecs ;
  3215.     DeltaMilliseconds = CurrentMilliseconds - LastMilliseconds ;
  3216.     LastMilliseconds = CurrentMilliseconds ;
  3217.  
  3218.    /*************************************************************************
  3219.     * Find out how much idle time was counted.    Adjust it to persecond.     *
  3220.     *************************************************************************/
  3221.  
  3222.     CurrentCount = *Parms->Counter - LastCounter ;
  3223.     LastCounter = *Parms->Counter ;
  3224.     CurrentCount = (CurrentCount * 1000) / DeltaMilliseconds ;
  3225.  
  3226.    /*************************************************************************
  3227.     * Tell the owner window to refresh its statistics.                *
  3228.     *************************************************************************/
  3229.  
  3230.     WinPostMsg ( Parms->Owner, WM_REFRESH, MPFROMLONG(CurrentCount), 0L ) ;
  3231.   }
  3232. }
  3233.